GVKun编程网logo

无法在AsyncTask内未为ProgressDialog调用Looper.prepare()的线程内创建处理程序

143

对于无法在AsyncTask内未为ProgressDialog调用Looper.prepare感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍的线程内创建处理程序,并为您提供关于android–

对于无法在AsyncTask内未为ProgressDialog调用Looper.prepare感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍的线程内创建处理程序,并为您提供关于android – AsyncTask onPreExecute progressdialog、android – AsyncTask与ProgressDialog vs方向更改、android – AsyncTask没有显示ProgressDialog、android – java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序的有用信息。

本文目录一览:

无法在AsyncTask内未为ProgressDialog调用Looper.prepare()的线程内创建处理程序

无法在AsyncTask内未为ProgressDialog调用Looper.prepare()的线程内创建处理程序

我不明白为什么会收到此错误。我正在使用AsyncTask在后台运行一些进程。

我有:

protected void onPreExecute() {    connectionProgressDialog = new ProgressDialog(SetPreference.this);    connectionProgressDialog.setCancelable(true);    connectionProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);    connectionProgressDialog.setMessage("Connecting to site...");    connectionProgressDialog.show();    downloadSpinnerProgressDialog = new ProgressDialog(SetPreference.this);    downloadSpinnerProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);    downloadSpinnerProgressDialog.setMessage("Downloading wallpaper...");}

当我doInBackground()根据情况进入时:

[...]    connectionProgressDialog.dismiss();downloadSpinnerProgressDialog.show();[...]

每当我尝试downloadSpinnerProgressDialog.show()我都会收到错误消息。

有想法吗?

答案1

小编典典

该方法show()必须从被调用用户界面(UI)螺纹,而doInBackground()在不同的螺纹,其是主要的原因,运行AsyncTask被设计。

你必须调用show()无论是在onProgressUpdate()onPostExecute()

例如:

class ExampleTask extends AsyncTask<String, String, String> {    // Your onPreExecute method.    @Override    protected String doInBackground(String... params) {        // Your code.        if (condition_is_true) {            this.publishProgress("Show the dialog");        }        return "Result";    }    @Override    protected void onProgressUpdate(String... values) {        super.onProgressUpdate(values);        connectionProgressDialog.dismiss();        downloadSpinnerProgressDialog.show();    }}

android – AsyncTask onPreExecute progressdialog

android – AsyncTask onPreExecute progressdialog

当onPreExecute函数执行时,我有一个AsyncTask,它给了我一个例外

** java.lang.IllegalStateException: View
com.android.internal.policy.impl.PhoneWindow$DecorView@44ea0e20
has already been added to the window
manager.**

当progressDialog的show()方法被调用时.

我的活动

public class TopNewsActivity extends ListActivity {

public static final String LOG_TAG = "Infra";
private ProgressDialog progressDialog;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.listplaceholder);
    new BackgroundAsyncTask().execute();
}

public class BackgroundAsyncTask extends AsyncTask<String,Integer,ArrayList<HashMap<String,String>>> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog = new ProgressDialog(TopNewsActivity.this);
        progressDialog.setCancelable(true);
        progressDialog.setMessage("Loading...");
        progressDialog.setProgressstyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setProgress(0);
        progressDialog.show();
    }

    @Override
    protected ArrayList<HashMap<String,String>> doInBackground(String... paths) {
        ArrayList<HashMap<String,String>> mylist = new ArrayList<HashMap<String,String>>();

        String xml = XMLfunctions.getTopNewsXML();
        Document doc = XMLfunctions.XMLfromString(xml);

        int numResults = XMLfunctions.numResults(doc);
        Log.d(LOG_TAG,"Number of Results: " + numResults);
        if ((numResults <= 0)) {
            Toast.makeText(TopNewsActivity.this,"No Result Found",Toast.LENGTH_LONG).show();
            finish();
        }

        NodeList nodes = doc.getElementsByTagName("result");

        for (int i = 0; i < nodes.getLength(); i++) {
            HashMap<String,String> map = new HashMap<String,String>();

            Element e = (Element) nodes.item(i);
            map.put("id",XMLfunctions.getValue(e,"id"));
            map.put("title","title"));
            mylist.add(map);
        }
        return mylist;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
    }

    protected void onPostExecute(ArrayList<HashMap<String,String>> result) {
        listadapter adapter = new SimpleAdapter(TopNewsActivity.this,result,R.layout.list_item,new String[] { "title" },new int[] { R.id.item_title });
        setlistadapter(adapter);
        progressDialog.dismiss();

        final ListView lv = getListView();

        lv.setTextFilterEnabled(true);  
        lv.setonItemClickListener(new OnItemClickListener() {
            @SuppressWarnings("unchecked")
            @Override
            public void onItemClick(AdapterView<?> a,View view,final int position,long id) {

                    HashMap<String,String> o = (HashMap<String,String>) lv.getItemAtPosition(position);

                    Intent i = new Intent(TopNewsActivity.this,NewsDetails.class);
                    i.putExtra("content_id",o.get("id"));
                    i.putExtra("title",o.get("title"));
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

                    View v = TopNewsGroup.group.getLocalActivityManager().startActivity("ShowNews",i).getDecorView();

                    // Again,replace the view
                    TopNewsGroup.group.setContentView(v);

            }
        });

    }

}

public class MySimpleAdapter extends SimpleAdapter {
     public MySimpleAdapter(Context context,List<? extends Map<String,?>> data,int resource,String[] from,int[] to) {
        super(context,data,resource,from,to);
        // Todo Auto-generated constructor stub
}

}
}

请帮忙!!!!!

解决方法

progressdialogs和contexts有一个常见的问题,它一直发生在我身上,并且在这个问题上有一个关于android doc的部分.当上下文实际上是您的java类的名称后跟“.this”时,您可能已使用“this”的上下文声明它.
dialog = ProgressDialog.show(Example.this,"","Doing stuff. Please wait...",true);

这是因为您希望progressDialog在主类中显示,而不是在Async类中显示.

如果这不能解决问题,您需要发布代码.

android – AsyncTask与ProgressDialog vs方向更改

android – AsyncTask与ProgressDialog vs方向更改

经过几个绝望的日子,我终于创造了几乎成功的榜样.

目标:在onCreate中我想在AsyncTask中下载和解析XML文件,显示进度对话框,更新UI并关闭对话框.

问题:当方向更改时,Activity重新启动,AsyncTask失去对它的引用.关于它有很多问题和博客.但我无法找出为什么这个特定的解决方案不起作用.或者在这种情况下android如何处理对话框.

状态:当我启动应用程序时一切正常.我可以旋转设备,我可以通过菜单再次手动启动任务.但是在任务完成后我再次更改方向对话框弹出(如预期的那样)并且没有其他任何事情发生.没有进度改变,没有对话解雇. AsyncTask正常完成.

代码:

package com.test;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

public class Test extends tabactivity {
DownloadFileAsync task;
ProgressDialog   progressDialog;
static final int PROGRESS_DIALOG = 0;

private static Data      data;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {       
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    /* - Run from different locations bug - */
    //http://code.google.com/p/android/issues/detail?id=2373
    if (!isTaskRoot()) {
        final Intent intent = getIntent();
        final String intentAction = intent.getAction();
        if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) &&
                intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
            finish();
        }
    }
    /* - /Run from different locations bug  */

    /* -------------- Tabs ---------------- */
    Resources res = getResources();
    TabHost mTabHost = getTabHost();
    mTabHost.addTab(mTabHost.newTabSpec("overview").setIndicator("MYTAB1",res.getDrawable(R.drawable.ic_tab_home)).setContent(R.id.tab1));      
    mTabHost.setCurrentTab(0);
    /* -------------- /Tabs --------------- */

    /* -------------- /Data --------------- */
    task = (DownloadFileAsync)getLastNonConfigurationInstance();
    if(task!= null) {
        task.setActivity(this);
    } else {
        if(data == null) {
            File datafile = this.getFileStreamPath("data.dat");
            if(datafile.exists()){
                //Log.d("log","File exists!");
                try {
                    long time = System.currentTimeMillis();
                    ObjectInputStream obj = new ObjectInputStream(new FileInputStream(datafile));
                    data = (Data)obj.readobject();
                    obj.close();
                    Log.d("time","loaded in:"+(System.currentTimeMillis()- time));

                    if(data.isUpToDate() || !isOnline()){
                        update();
                    }
                } catch (Exception e) {
                    e.printstacktrace();
                    datafile.delete();
                    data = null;
                }
                //Log.d("log","Passed?");
            }
        }       
        /* DEBUG if(data == null || !data.isUpToDate())*/ this.synchronize(); 
    }
    /* -------------- /Data --------------- */

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    menu.add("Synchronize").setIcon(R.drawable.ic_menu_refresh);     
    return true;
}

@Override
public boolean onoptionsItemSelected(MenuItem item) {
    synchronize();
    return super.onoptionsItemSelected(item);
}

@Override
public Object onRetainNonConfigurationInstance() {
    if(task != null) task.setActivity(null);      
    return(task);
}

protected Dialog onCreateDialog(int id) {
    switch (id) {
    case PROGRESS_DIALOG:
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Aktualizuji ...");
        progressDialog.setProgressstyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setCancelable(false);            
        //progressDialog.show();            
        return progressDialog;
    default:
        return null;
    }
}

public void update() {

}

private void onTaskCompleted() {
    task = null;        
    dismissDialog(PROGRESS_DIALOG);     
    Log.d("tok","Task.onComplete");
    update();       
}

public void synchronize(){
    if(isOnline()) {
        showDialog(PROGRESS_DIALOG);
        progressDialog.setProgress(0); // <-- this is the last time progressDialog updates
        task = new DownloadFileAsync(this);
        task.execute();
    }
}

public boolean isOnline() {
    ConnectivityManager cm =
        (ConnectivityManager) getSystemService(waspActivity.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnectedOrConnecting()) {
        return true;
    }
    return false;
}

private static class DownloadFileAsync extends AsyncTask<String,String,String> {
    private Data tempData;
    private Test activity;
    private int progress = 0;
    private File Metafile;
    private File tempDir;
    private FileOutputStream fos;

    public DownloadFileAsync(Test activity) {
        this.setActivity(activity);


        ... some more init ...
    }

    public void setActivity(Test activity) {
        this.activity = activity;           
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        tempData = new Data();
    }

    @Override
    protected String doInBackground(String... aurl) {
        try {

        ... some heavy load  ...
        //this.progress = someValue;                

        } catch (Exception e) {
            Log.d("Error","Error while processing files. Code:"+e.getMessage());
            e.printstacktrace();
        }

        //Log.d("time","Task "+(System.currentTimeMillis() - time));
        return null;

    }
    protected void onProgressUpdate(String... progress) {            
        if(activity != null) activity.progressDialog.setProgress(this.progress);
    }

    @Override
    protected void onPostExecute(String unused) {
        data = tempData;
        tempData = null;
        if(activity != null) {
            activity.onTaskCompleted();
            activity = null;
        }
    }
}

}

解决方法

昨天,我写了一个 blog post,它描述了使用保留的片段处理配置更改.

TL; DR是在Fragment中使用你的AsyncTask托管,在Fragment上调用setRetainInstance(true),并通过保留的Fragment将AsyncTask的进度/结果报告给它的Activity.

android – AsyncTask没有显示ProgressDialog

android – AsyncTask没有显示ProgressDialog

我正在使用AsyncTask(我在我的主要活动中开始)来加载一些数据:

Context context = VehicleTabView.this;
ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Loading...");
new LoadingVehicles(context,progressDialog).execute(null,null,null);

这是Asyncclass:

package com.example.schedule_vehicles;

import com.example.utils.VehicleNames;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;

    // Showing a ProgressDialog once loading the list of vehicles is completed using an AsyncTask
    public class LoadingVehicles extends AsyncTask<Void,Void,Void> {
    Context context;
    ProgressDialog progressDialog;

    public LoadingVehicles(Context context,ProgressDialog progressDialog) {
        this.context = context;
        this.progressDialog = progressDialog;
    }

    @Override
    protected void onPreExecute() {
        progressDialog.show();
    }

    @Override
    protected Void doInBackground(Void... params) {
        new VehicleNames(context);

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        progressDialog.dismiss();
    }
}

ProgressDialog未在屏幕上显示的问题.

我输入Log.d,看看程序是否经历了所有阶段 – onPreExecute,doInBackground,onPostExecute,它正在经历所有阶段并完成我需要的工作.但是ProgressDialog没有显示出来.我读了很多关于这个东西的信息,似乎PRE和POST执行是由主线程启动的,它被DOINBACKGROUND方法阻塞,这就是没有看到ProgressDialog的原因.我试图找到一些答案如何解决 – 但没有成功.

如果有人遇到此问题,请分享您的经验.非常感谢!

解决方法

您正在将ProgressDialog传递给Task,只是在启动AsyncTask之前show()它,而不是在AsyncTask中.

android – java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序

android – java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序

嗨,我的代码有问题.我的代码是
progressD = ProgressDialog.show(MenuUtama.this,"","Uploading files to server.....",false);
Thread thread = new Thread(new Runnable(){
       public void run(){
           //doFileUpload();
           try {
            // setiap parameter yang akan dikirim melalui http
            // harus encode agar
            // dapat terbaca dengan baik oleh server
            Cursor c = helper.getAll1(almagId);
            Cursor cr = helper.getUpImage(almagId);
                if(c.movetoFirst()){
                    //progressD = ProgressDialog.show(context,title,message)
                        do{
                            String kdstore = URLEncoder.encode(helper.getKdStore(c).toString(),"utf-8");
                            String nama = URLEncoder.encode(helper.getNama(c).toString(),"utf-8");
                            String alamat = URLEncoder.encode(helper.getAlamat(c).toString(),"utf-8");
                            String kdpos = URLEncoder.encode(helper.getKdPos(c).toString(),"utf-8");
                            String notelp = URLEncoder.encode(helper.getNotel(c).toString(),"utf-8");
                            String lng = URLEncoder.encode(helper.getlng(c).toString(),"utf-8");
                            String lat = URLEncoder.encode(helper.getLat(c).toString(),"utf-8");
                            String perush = URLEncoder.encode(helper.getPerus(c).toString(),"utf-8");
                            //String gambar = URLEncoder.encode(helper.getGamb(c).toString(),"utf-8");

                            //Toast.makeText(this,kdstore,Toast.LENGTH_LONG).show();
                            //System.out.println(gambar);
                            url += "?kode_toko=" + kdstore + "&&nama=" + nama + "&&alamat=" + alamat + 
                            "&&kode_pos=" + kdpos + "&&no_telp=" + notelp + "&&longitude=" + lng + "&&latitude=" + lat +
                            "&&perusahaan=" + perush;
                            getRequest(url);
                            url = "http://10.234.165.232/upload_get.PHP";
                        }while(c.movetoNext());
            }
            if(cr.movetoFirst()){
                do{
                    String kdstore = URLEncoder.encode(helper.getKdstore1(cr),"utf-8");
                    String gambar = URLEncoder.encode(helper.getGam1(cr),"utf-8");
                    url1 += "?kode_toko1=" + kdstore + "&&gambar1=" + gambar;
                    getRequest1(url1);
                    url1 = "http://10.234.165.232/upload_get2.PHP";
                }while(cr.movetoNext());
            }

            } catch (UnsupportedEncodingException e) {
                // Todo Auto-generated catch block
                e.printstacktrace();
            }
           MenuUtama.this.runOnUiThread(new Runnable(){
               public void run() {
                   if(progressD.isShowing())
                       progressD.dismiss();
               }
           });
       }
});
thread.start();
return(true);

和这样的错误:

FATAL EXCEPTION: Thread-9
java.lang.RuntimeException: 
Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:121)
    at android.widget.Toast.<init>(Toast.java:68)
    at android.widget.Toast.makeText(Toast.java:231)
    at com.sat.alfaloc.MenuUtama.getRequest(MenuUtama.java:160)
    at com.sat.alfaloc.MenuUtama$1.run(MenuUtama.java:101)
    at java.lang.Thread.run(Thread.java:1096)

如果活动将数据保存到服务器我命令进度条可以运行,但如果没有这不起作用..我应该怎么做才能解决这个问题?

解决方法

由于您正在使用活动上下文的线程,您可能会收到错误.

您应该使用AsyncTask而不是普通线程.
在AsyncTask中,有一个onPreExecute()和onPostExecute()方法,它们在主线程上执行,并且有一个方法doInBackground()将在后台执行,以便您可以轻松实现长期进程.

你可以参考this example

关于无法在AsyncTask内未为ProgressDialog调用Looper.prepare的线程内创建处理程序的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于android – AsyncTask onPreExecute progressdialog、android – AsyncTask与ProgressDialog vs方向更改、android – AsyncTask没有显示ProgressDialog、android – java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序等相关内容,可以在本站寻找。

本文标签: