使用Toast在AsyncTask的方法调用问题方法、问题、Toast、AsyncTask

2023-09-13 00:54:29 作者:⑧離⑧弃ò

嘿,大家, 我有一个的AsyncTask的员额一些数据到服务器。它通过调用我从doInBackground写了一个静态方法做到这一点。当我运行的AsyncTask的,我送活动的背景下,所谓的execute(),这是我发送给我的静态方法,因为它需要它来敬酒,如果出现错误,而谈话的服务器。不过,我得到这个错误时,吐司是在静态方法:

  12月4号至21号:49:16.689:ERROR / AndroidRuntime(2123):致命异常:AsyncTask的#1
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):java.lang.RuntimeException的:一个错误而执行doInBackground发生()
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在android.os.AsyncTask $ 3.done(AsyncTask.java:200)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在java.util.concurrent.FutureTask中$ Sync.innerSetException(FutureTask.java:274)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在java.util.concurrent.FutureTask.setException(FutureTask.java:125)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:308)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在java.util.concurrent.FutureTask.run(FutureTask.java:138)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:581)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在java.lang.Thread.run(Thread.java:1019)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):java.lang.RuntimeException的:所致。内螺纹已经不叫尺蠖prepare无法创建处理器()
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在android.os.Handler< INIT>(Handler.java:121)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在android.widget.Toast< INIT>(Toast.java:68)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在android.widget.Toast.makeText(Toast.java:23
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在com.microogle.dev.util.ServerConnections.PostToLoginPage(ServerConnections.java:36)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在com.microogle.dev.Whiteboard.WhiteboardLogin $ LoginTask.doInBackground(WhiteboardLogin.java:150)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在com.microogle.dev.Whiteboard.WhiteboardLogin $ LoginTask.doInBackground(WhiteboardLogin.java:1)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在android.os.AsyncTask $ 2.call(AsyncTask.java:185)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:306)
12月4日至二十一号:49:16.689:ERROR / AndroidRuntime(2123):4 ...更多
 

后跟一个泄露的窗口错误,。我假定这是因为随着传递给吐司在静态方法的上下文中的错误。该AsyncTask的是:

 私有类LoginTask扩展的AsyncTask<虚空,虚空,虚空> {

    私人WhiteboardLogin活动;
    私人语境callingContext;
    私人ProgressDialog对话框;
    私人字符串的用户,通过;
    私人布尔sendIntent = TRUE,loginError =假,populateError = FALSE;

    公共LoginTask(WhiteboardLogin活动,用户字符串,字符串传递,上下文callingContext){
        this.activity =活动;
        this.user = user.trim();
        this.pass = pass.trim();
        this.callingContext = callingContext;
    }
@覆盖
    保护无效doInBackground(虚空...... PARAMS){
        ArrayList的<的NameValuePair> namevaluepairs中=新的ArrayList<的NameValuePair>();
        nameValuePairs.add(新BasicNameValuePair(用户,用户));
        nameValuePairs.add(新BasicNameValuePair(通,通));
        sessionUser =用户;
        sessionPassword =通;
        //帖子的用户名和密码登录页面,祝酒词一个错误,如果登录不工作
        如果(ServerConnections.PostToLoginPage(callingContext,namevaluepairs中,activity.getString(R.string.loginPageURI))== 1){
            dialog.dismiss();
            sendIntent = FALSE;
            loginError = TRUE;
            publishProgress();
           返回null;
        }
        其他{
           userDataList = populateUserDataList(callingContext,用户通过);
           如果(userDataList == NULL){
               dialog.dismiss();
               sendIntent = FALSE;
               populateError = TRUE;
               返回null;
           }
       }
       返回null;
    }
 

解决方案 AsyncTask的原理

在doInBackground的code()方法运行在自己的线程,所以你不能从那里直接访问任何UI元素,因为它们在用户界面上运行线。

所以,你有两个选择。

您处理所有的用户界面的东西在on$p$pExecute()和onPostExecute()方法,该方法在UI线程上运行。

您处理的onProgressUpdate()方法,它也运行在UI线程上。您可以从doInBackground()调用publishProgress().

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

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;
    }

解决方案

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.

So you got two options.

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

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().