AsyncTask 方法调用中的 Toast 问题 [英] Problem with Toast in AsyncTask method call

查看:19
本文介绍了AsyncTask 方法调用中的 Toast 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,
我有一个 AsyncTask 将一些数据发布到服务器.它通过调用我从 doInBackground 编写的静态方法来实现.当我运行 AsyncTask 时,我将调用 execute() 的活动的上下文发送到我的静态方法,因为如果在与服务器交谈时出现问题,它需要它来制作 Toast.但是,在静态方法中制作 Toast 时出现此错误:

Hey Everybody,
I have an AsyncTask that posts some data to a server. It does this by calling a static method that I wrote from doInBackground. When I run the AsyncTask, I send the context of the activity that called execute(), which I send to my static method, because it needs it to make a Toast if something goes wrong while talking to the server. However, I get this error when a Toast is made in the static method:

04-21 12:49:16.689: ERROR/AndroidRuntime(2123): FATAL EXCEPTION: AsyncTask #1
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): java.lang.RuntimeException: An error occured   while executing doInBackground()
04-21 12:49:16.689: ERROR/AndroidRuntime(2123):at android.os.AsyncTask$3.done(AsyncTask.java:200)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.lang.Thread.run(Thread.java:1019)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at android.os.Handler.<init>(Handler.java:121)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at android.widget.Toast.<init>(Toast.java:68)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at android.widget.Toast.makeText(Toast.java:23
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at com.microogle.dev.util.ServerConnections.PostToLoginPage(ServerConnections.java:36)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at com.microogle.dev.Whiteboard.WhiteboardLogin$LoginTask.doInBackground(WhiteboardLogin.java:150)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at com.microogle.dev.Whiteboard.WhiteboardLogin$LoginTask.doInBackground(WhiteboardLogin.java:1)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): ... 4 more

接着是窗口泄漏错误.我假设这是因为在静态方法中传递给 Toast 的上下文出错.异步任务是:

Which is followed by a leaked window error. I am assuming this is because of an error with the context passed to the Toast in the static method. The AsyncTask is:

private class LoginTask extends AsyncTask<Void, Void, Void> {

    private WhiteboardLogin activity;
    private Context callingContext;
    private ProgressDialog dialog;
    private String user, pass;
    private boolean sendIntent = true, loginError = false, populateError = false;

    public LoginTask(WhiteboardLogin activity, String user, String pass, Context callingContext){
        this.activity = activity;
        this.user = user.trim();
        this.pass = pass.trim();
        this.callingContext = callingContext;
    }
@Override
    protected Void doInBackground(Void... params) {
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("user",user));
        nameValuePairs.add(new BasicNameValuePair("pass",pass));
        sessionUser = user;
        sessionPassword = pass;
        //Posts the username and password to the login page and toasts an error if the login doesn't work 
        if(ServerConnections.PostToLoginPage(callingContext, nameValuePairs, activity.getString(R.string.loginPageURI)) == 1){
            dialog.dismiss();
            sendIntent = false;
            loginError = true;
            publishProgress();
           return null;
        }
        else{
           userDataList = populateUserDataList(callingContext, user,pass);
           if(userDataList == null){
               dialog.dismiss();
               sendIntent = false;
               populateError = true;
               return null;
           }
       }
       return null;
    }

推荐答案

doInBackground() 方法中的代码在其自己的线程上运行,因此您无法从那里直接访问任何 UI 元素,因为它们在 UI 线程上运行.

The code in the doInBackground() method runs on its own thread so you cannot access any UI element from there directly as they are running on the UI thread.

所以你有两个选择.

  1. 您在 onPreExecute()<中处理所有 UI 内容onPostExecute() 方法在 UI 线程上运行.

  1. You handle all the UI stuff in the onPreExecute() and onPostExecute() method which run on the UI thread.

您在 onProgressUpdate() 中处理 UI 内容 方法也运行在 UI 线程上.您可以通过调用 publishProgress() 从 doInBackground() 中触发此方法.

You handle UI stuff in the onProgressUpdate() method which also runs on the UI thread. You can trigger this method from within doInBackground() by calling publishProgress().

这篇关于AsyncTask 方法调用中的 Toast 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆