2

我在 AsyncTask 中从数据库中获取数据,如果它为空,我想 Toast 一个警告文本。我在 AsyncTask 中尝试过,但我了解到它没有在工作线程中调用。这是我的 doInBackground 方法:

protected String doInBackground(Boolean... params) {
        String result = null;
        StringBuilder sb = new StringBuilder();
        try {   
            HttpClient httpclient = new DefaultHttpClient();
            HttpGet httppost = new HttpGet( "http://191.162.2.235/getProducts.php?login=1&user_name="+UserName+"&user_pass="+Password);
            HttpResponse response = httpclient.execute(httppost);
            if (response.getStatusLine().getStatusCode() != 200) {
                Log.d("MyApp", "Server encountered an error");
            }
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(
                            response.getEntity().getContent(), "UTF8"));  
            sb = new StringBuilder();
            sb.append(reader.readLine() + "\n");
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            result = sb.toString();
         if (  result == null  )        {
        //   Toast.makeText(getApplicationContext(), "You entered wrong values.", Toast.LENGTH_LONG).show(); 
             asyncTask.cancel(true);
            Intent  inte=new Intent(MainActivity.this, MainActivity.class);
            inte.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
            inte.addCategory(Intent.CATEGORY_HOME);
                startActivity(inte);                                
            }
        } 
        catch (Exception e) {
            Log.e("log_tag", "Error converting result " + e.toString());
                             }
        return result;
    }

我取消了任务并在我的代码中创建了一个新意图。你不在乎他们。你看 Toast.makeText.. 行,我试过这样,当然它会出错。我怎样才能做到这一点?如果在 AsyncTask 中没有调用它,我应该如何调用?

4

4 回答 4

10

doInbackground在后台线程上调用。因此,您不能在 ui 线程以外的其他线程上更新 ui。

您可以在doInbackground基于结果更新 ui 中返回结果,onPostExecute或者使用runOnUithread哪个是活动类的方法。

runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        // toast here
                    }
                });

或者

protected String doInBackground(Boolean... params) {
// other code
return "status"
} 
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
    Toast.makeText(getApplicationContext(),"My status is"+result,Toast.LENGTH_SHORT).show(); 
}

编辑

正如@codeMagic 建议的那样,将您的 startActivity 也移动到onPostExecute. 此外,当您仍有代码要运行时,您不想取消 asynctask 运行

于 2013-10-10T13:54:12.537 回答
2

Toast 消息必须在主/UI 线程中调用。
你可以解决这个问题的方法是:

  • 将 Toast 放入 AsyncTask 的 onPostExecute 中
  • 创建一个将在 UI 线程上运行的普通 Toast 包装器,使用:

例子:

activity.runOnUiThread(new Runnable() {

@Override
public void run() {
     Toast.make...
}
});
于 2013-10-10T13:57:22.517 回答
2

如果你想这样做,handler 那么代码将是

在活动类中声明 Handler handler = new Handler();为成员变量并使用以下显示 tost

handler.post( new Runnable(){
   public void run(){
Toast.makeText(getApplicationContext(), "You entered wrong values.",Toast.LENGTH_LONG).show(); 
       }
});
于 2013-10-10T13:58:21.037 回答
2

您可以将主线程的Handler传递给AsyncTask,然后使用Handler来调度一个发布toast消息的任务。这是 Handler 类的 java 文档:

http://developer.android.com/reference/android/os/Handler.html

基本上,您应该在主/UI 线程中创建该对象(它会自动绑定到主/UI 线程的 Looper)。然后你会将它传递给你的 AsyncTask。然后,当您需要显示消息时,您可以使用 Handler.post(Runnable) 方法

于 2013-10-10T14:02:59.373 回答