Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/179.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AsyncTask中UI操作的疑难解答(OnProgressDialog,Toasts)_Java_Android_Multithreading_Android Asynctask - Fatal编程技术网

Java AsyncTask中UI操作的疑难解答(OnProgressDialog,Toasts)

Java AsyncTask中UI操作的疑难解答(OnProgressDialog,Toasts),java,android,multithreading,android-asynctask,Java,Android,Multithreading,Android Asynctask,我试图在AsyncTask中显示ProgressDialog,但遇到错误无法在未调用Looper.prepare()的线程内创建处理程序。 所以我搜索了一下,发现以前有人有这个问题 我采用了第二个答案,你可以在那里看到,并以这种方式实现了我的异步任务。现在一切都很好,但我想一定有更好的方式来显示对话框 这是我修复后的任务 private class MyAsyncTask extends AsyncTask<Void, Void, ArrayList</*SomeObject*/&g

我试图在AsyncTask中显示ProgressDialog,但遇到错误
无法在未调用Looper.prepare()的线程内创建处理程序
。
所以我搜索了一下,发现以前有人有这个问题

我采用了第二个答案,你可以在那里看到,并以这种方式实现了我的异步任务。现在一切都很好,但我想一定有更好的方式来显示对话框

这是我修复后的任务

private class MyAsyncTask extends AsyncTask<Void, Void, ArrayList</*SomeObject*/>> {
    ProgressDialog mDialog;

    private MyAsyncTask() {
        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                mDialog = new ProgressDialog(getActivity());
            }
        });
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mDialog.setMessage("AsyncTask is starting...");
                mDialog.show();
            }
        });
    }

    @Override
    protected ArrayList</*SomeObject*/> doInBackground(Void... params) {
        // some non UI related code...
    }

    @Override
    protected void onPostExecute(ArrayList</*SomeObject*/> someObjects) {
        super.onPostExecute(exams);
        // some code...
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mDialog.dismiss();
            }
        });
    }
}
私有类MyAsyncTask扩展了AsyncTask{
进步对话;
私有MyAsyncTask(){
getActivity().runOnUiThread(新的Runnable()){
公开募捐{
mDialog=newprogressdialog(getActivity());
}
});
}
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
getActivity().runOnUiThread(新的Runnable()){
@凌驾
公开募捐{
setMessage(“异步任务正在启动…”);
mDialog.show();
}
});
}
@凌驾
受保护的ArrayList doInBackground(无效…参数){
//一些与UI无关的代码。。。
}
@凌驾
受保护的void onPostExecute(ArrayList someObjects){
super.onPostExecute(考试);
//一些代码。。。
getActivity().runOnUiThread(新的Runnable()){
@凌驾
公开募捐{
mDialog.discouse();
}
});
}
}
我的问题是

  • 是否有更好的方式显示对话框

  • 为什么我只在这个特定的异步任务中得到错误?(下面的代码运行良好)

  • 我运行AsyncTask一百次,您可以在下面看到,它从未崩溃,而第一个任务从未成功执行。一定有什么东西我看不见

    private class MyAsyncTask extends AsyncTask<String, Void, String> {
        private final ProgressDialog dialog = new ProgressDialog(mContext);
    
        private LoginConnectTask() {
        }
    
        protected void onPreExecute() {
            super.onPreExecute();
            dialog.setMessage("aMessage");
            dialog.show();
        }
    
        protected String doInBackground(String... strings) {
            return fancyFunction(strings[0], strings[1]);
        }
    
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            if (s != null) {
                Toast.makeText(mContext, s, Toast.LENGTH_LONG).show();
            }
            dialog.dismiss();
        }
    }
    
    私有类MyAsyncTask扩展了AsyncTask{
    private final ProgressDialog=新建ProgressDialog(mContext);
    专用登录连接任务(){
    }
    受保护的void onPreExecute(){
    super.onPreExecute();
    setMessage(“aMessage”);
    dialog.show();
    }
    受保护的字符串背景(字符串…字符串){
    返回fancyFunction(字符串[0],字符串[1]);
    }
    受保护的void onPostExecute(字符串s){
    super.onPostExecute(s);
    如果(s!=null){
    Toast.makeText(mContext,s,Toast.LENGTH_LONG).show();
    }
    dialog.dismise();
    }
    }
    
    所有
    AsyncTask
    方法,除了
    doInBackground()
    UI线程上运行。因此,没有理由或希望在
    AsyncTask
    内部使用
    runOnUiThread()
    ,而且它通常会导致问题(据我所见)

    因此,在构造函数中不需要它,而且在这种情况下似乎根本不需要构造函数。另外,在
    onPreExecute()
    中,您只需显示
    对话框
    ,因为它在
    UI线程上运行。在
    onPostExecute()
    中取消它也是一样的

    所以直接回答你的问题,

    是否有更好的方式显示对话框

    不,您在第二位代码中执行此操作的方式是完全正常的

    为什么我只在这个特定的异步任务中得到错误?(下面的代码运行良好)


    在没有看到所有代码的情况下不确定确切原因,但正如Raghunandan所说,“当您从非ui线程更新ui时,通常会发生错误”,但如上所述,没有理由在
    异步任务中使用
    runOnUiThread()
    。至少我知道没有理由,在大多数情况下也没有理由

    错误通常发生在从非ui线程更新ui时。是否从主线程调用asynctask?但为什么它们不总是发生。。。我运行AsyncTask一百次,您可以在下面看到,它从未崩溃,而第一个任务从未成功执行。一定有什么东西我看不见!我猜,您正在doInnBackground()方法中创建一个处理程序……您的第二个代码应该正常运行,因为除了doinbackground之外的所有方法都在UI线程上运行。您可以从onPreExecute()和onPostExecute()执行UI操作,而不会出现任何错误。fancyFunction方法可能有问题。不要从doInBackground或fancyFunction方法中更新UI。