Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.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 使用appcontext从后台线程显示AlertDialog_Java_Android_Multithreading - Fatal编程技术网

Java 使用appcontext从后台线程显示AlertDialog

Java 使用appcontext从后台线程显示AlertDialog,java,android,multithreading,Java,Android,Multithreading,是否可以使用对getApplicationContext()的引用从后台线程引发AlertDialog 我试着用那个代码,但它不起作用 new Thread(){ public void run(){ new AlertDialog.Builder(appcontext) .setMessage("Test") .setPositiveButton("Ok", null) .s

是否可以使用对getApplicationContext()的引用从后台线程引发AlertDialog

我试着用那个代码,但它不起作用

    new Thread(){
        public void run(){
            new AlertDialog.Builder(appcontext)
            .setMessage("Test")
            .setPositiveButton("Ok", null)
            .show();
        }
    }.start();

提前感谢

不,您不想这样做。Android不允许UI在任何线程上工作,但允许UI线程,因为UI代码不是线程安全的。请参阅“无痛穿线”

您可以从另一个线程调用
Activity.runOnUiThread(Runnable)
(在特定的活动上),以强制代码在UI线程上运行。您还可以调用
View.post(Runnable)
(在特定视图上)使操作排队到UI线程上。有关这些选项和其他选项的更多详细信息,请参阅上述文章

然而,Android还提供了一种称为
AsyncTask
的东西,专门设计用于在单独的线程上运行某些东西,以及在UI线程上运行某些东西。这会自动使用Android的线程池,如果您没有任何理由使用明确的单独线程,这是一种简单、干净的方法:

从:

私有类下载文件任务扩展异步任务{
//在线程池线程上运行
受保护的长doInBackground(URL…URL){
int count=url.length;
长totalSize=0;
for(int i=0;i
不,您不想这样做。Android不允许UI在任何线程上工作,但允许UI线程,因为UI代码不是线程安全的。请参阅“无痛穿线”

您可以从另一个线程调用
Activity.runOnUiThread(Runnable)
(在特定的活动上),以强制代码在UI线程上运行。您还可以调用
View.post(Runnable)
(在特定视图上)使操作排队到UI线程上。有关这些选项和其他选项的更多详细信息,请参阅上述文章

然而,Android还提供了一种称为
AsyncTask
的东西,专门设计用于在单独的线程上运行某些东西,以及在UI线程上运行某些东西。这会自动使用Android的线程池,如果您没有任何理由使用明确的单独线程,这是一种简单、干净的方法:

从:

私有类下载文件任务扩展异步任务{
//在线程池线程上运行
受保护的长doInBackground(URL…URL){
int count=url.length;
长totalSize=0;
for(int i=0;i
您必须访问UI线程,其中任何一个:,或。

您必须访问UI线程,其中任何一个:,或。

如果无法从线程访问UI元素,则必须创建处理程序并从线程调用它

1-处理程序:处理来自其他线程的UI

 private Handler handler= new Handler() {
        public void handleMessage(Message msg){

            /*put your code here to update on UI*/

        } 
    }; 
2-在您的线程中,将其称为:

  Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
          handler.sendEmptyMessage(0);
    } 
  }); //thread
t.start();

不能从线程访问UI元素,必须创建处理程序并从线程调用它

1-处理程序:处理来自其他线程的UI

 private Handler handler= new Handler() {
        public void handleMessage(Message msg){

            /*put your code here to update on UI*/

        } 
    }; 
2-在您的线程中,将其称为:

  Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
          handler.sendEmptyMessage(0);
    } 
  }); //thread
t.start();

最简单的解决方案是使用异步任务

请尝试以下代码

  private class LaunchDialog extends AsyncTask<Void,Void,Void>{
        Context context;
        public LaunchDialog(Context ctx){
           context =  ctx;
         }

    @Override
    protected  ArrayList<CategoryObj> doInBackground(Void... params) {
        //do the task to be done on NON-UI thread , or NON-Blocking thread
       // publishProgress(null);
    }

        @Override
        protected void onProgressUpdate(Void... v){
           //stuff done on UI thread , can be invoked from doInBackground

        }
    @Override
    protected void onPostExecute(Void x){
            //stuff to be done after task executes(done on UI thread)

         new AlertDialog.Builder(context)
            .setMessage("Test")
            .setPositiveButton("Ok", null)
            .show();

    }
    @Override
    protected void onPreExecute(){
             //stuff to be done before task executes (done on UI thread)
    }
}

在这里阅读关于无痛线程的文章--

最简单的解决方案是使用异步任务

请尝试以下代码

  private class LaunchDialog extends AsyncTask<Void,Void,Void>{
        Context context;
        public LaunchDialog(Context ctx){
           context =  ctx;
         }

    @Override
    protected  ArrayList<CategoryObj> doInBackground(Void... params) {
        //do the task to be done on NON-UI thread , or NON-Blocking thread
       // publishProgress(null);
    }

        @Override
        protected void onProgressUpdate(Void... v){
           //stuff done on UI thread , can be invoked from doInBackground

        }
    @Override
    protected void onPostExecute(Void x){
            //stuff to be done after task executes(done on UI thread)

         new AlertDialog.Builder(context)
            .setMessage("Test")
            .setPositiveButton("Ok", null)
            .show();

    }
    @Override
    protected void onPreExecute(){
             //stuff to be done before task executes (done on UI thread)
    }
}

在这里阅读关于无痛线程的文章--

您不能在后台线程中更改UI。还有另一个线程可以执行UI活动

runOnUiThread(new Runnable() {

                                        @Override
                                        public void run() {
                                            //perform UI operations
                                        }
                                    });

不能在后台线程中更改UI。还有另一个线程可以执行UI活动

runOnUiThread(new Runnable() {

                                        @Override
                                        public void run() {
                                            //perform UI operations
                                        }
                                    });

此线程是否在activty之外?此线程是否在activty之外?此方法的问题是@AnujTenani,如果用户在异步任务执行期间导航到其他活动,则
上下文
与生成和显示
警报对话框
不再相关,这个答案现在已经过时了,你应该使用DialogFragment而不是Alertdialog。LaunchDialog应该是一个静态类,以避免上下文泄漏。上下文参数应该是WeakReference,以避免上下文泄漏。AlertDialog应始终在活动的桌面中关闭(如果您计划支持多窗口,则为桌面;如果不支持多窗口,则为暂停),否则会泄漏窗口。您不必使用DialogFragment,但它使生活变得更轻松此方法的问题是@AnujTenani,如果用户在异步任务执行期间导航到不同的活动,则
上下文
与构建和显示
AlertDialog
不再相关,这个答案现在已经过时了,你应该使用DialogFragment而不是Alertdialog。LaunchDialog应该是一个静态类,以避免上下文泄漏。上下文参数应该是WeakReference,以避免上下文泄漏。AlertDialog应始终在活动的桌面上关闭(如果您计划支持多窗口,则为桌面;如果不支持多窗口,则为暂停),否则将泄露胜利信息