我正在使用AsyncTask在我的程序中通过在10秒后调用一个方法进行多线程处理,但是却有这个例外:
08-04 11:49:29.565: E/log_tag(885): Error converting result java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Plz帮助我!!
编辑:这是AsyncTask的代码:
class Getphonenumber extends AsyncTask<String, Void, Void> {
public Void doInBackground(String... p) {
while (true) {
getPhno();
try {
Thread.sleep(10000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
};
'getPhno()'方法:
public void getPhno()
{
try{
HttpClient httpclient = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 10000); //Timeout Limit
List<NameValuePair> username = new ArrayList<NameValuePair>();
username.add(new BasicNameValuePair("username", user));
//Web Address
HttpPost httppost = new HttpPost("http://www.starretailshop.com/Log/Retrieve.php");
httppost.setEntity(new UrlEncodedFormEntity(username));
HttpResponse response = httpclient.execute(httppost);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httppost,
responseHandler);
Log.i("retrieve postData", response.getStatusLine().toString());
InputStream content = response.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
sendMsg(s,msg);
}
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
}
'sendMsg'方法:
private void sendMsg(String phoneNumber, String message)
{
try{
String phoneNumber1 = null;
if(phoneNumber.startsWith("+"))
{
phoneNumber1 = phoneNumber.substring(3);
}
else if(phoneNumber.startsWith("0"))
{
phoneNumber1 = phoneNumber.substring(1);
}
else
{
phoneNumber1=phoneNumber;
}
PendingIntent pi = PendingIntent.getActivity(this, 0,
new Intent(), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber1, null, message, pi, null);
Toast.makeText(this,"Msg sent to:" + phoneNumber1, Toast.LENGTH_LONG).show();
phnoList.add(phoneNumber);
phnoListd.add(phoneNumber1);
//phnumber = phoneNumber;
//================Update Database=====================
try{
HttpClient httpclient = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 10000); //Timeout Limit
List<NameValuePair> updatemsg = new ArrayList<NameValuePair>();
updatemsg.add(new BasicNameValuePair("outmsg1", message));
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HH:m:ss dd-MM-yyyy");
String TimeStampDB = sdf.format(cal.getTime());
updatemsg.add(new BasicNameValuePair("currentdatetime1",TimeStampDB));
updatemsg.add(new BasicNameValuePair("mobileno",phoneNumber));
//Web Address
HttpPost httppost = new HttpPost("http://www.starretailshop.com/Log/Update1.php");
httppost.setEntity(new UrlEncodedFormEntity(updatemsg));
HttpResponse response = httpclient.execute(httppost);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httppost,
responseHandler);
Log.i("update1 postData", response.getStatusLine().toString());
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
//================================================
}catch(Exception e)
{
e.printStackTrace();
Toast.makeText(this,"Error occured", Toast.LENGTH_LONG).show();
}
}
最后,我在Button的onClickListener中调用new Getphonenumber().execute();
。
答案 0 :(得分:3)
我认为问题在于,您正在尝试从后台线程更新UI组件。
例如,在AsyncTask中考虑这个方法,
protected Void doInBackground(String ... x) {
while (true) {
System.out.println(x[0]);
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
此方法仅等同于后台线程。在Andorid中,您只能从主UI线程更新UI,当您尝试从任何其他方法执行此操作时,您将获得此异常。
所以尽量避免这种情况。如果要更新UI,请使用AsyncTask的onPostExecute()。
编辑1
这是你的问题。从sendMsg方法中删除toast,它应该可以正常工作。
答案 1 :(得分:2)
使用runOnUiThread从非Ui Thread.like更新UI作为您提供的代码。您正在显示来自后台线程的Toast消息,因此将runOnUiThread中的Toast消息放入:
Current_Activity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(this,"Msg sent to:" + phoneNumber1, Toast.LENGTH_LONG).show();
}
});
答案 2 :(得分:1)
不要在doBackround中创建一个sleep线程,而是在你执行.execute()之前。我想这会有所帮助。