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

7

你好,我有一个关于代码的问题。我的代码是:

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)

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

4个回答

13

可能您出现错误是因为您在使用活动上下文的线程中。

您应该使用AsyncTask而不是普通线程。 在AsyncTask中,有一个onPreExecute()onPostExecute()方法,在主线程中执行,还有一个doInBackground()方法,在后台执行,这样您可以轻松实现长时间的进程。

您可以参考这个示例


5
有时候你可能会遇到这个问题,即使有问题的代码在Activity内部(就像我使用Unity游戏引擎时一样)。
以下代码对我有效。
        this.runOnUiThread(new Runnable() {
           public void run() {
              //Your code here
              ...
           }
        });

4

在UI线程上运行指定的操作

ActivityName.runOnUiThread(new Runnable() {
   public void run() {
      //put your code here
   }
});

2

当您使用AsyncTask并在doInBackground线程中运行进程时,不能执行Toast等功能,例如打开新的fragment。

当遇到这个特定的错误时,请尝试使用以下代码创建一个新线程来运行您的代码。它会将其带到前台,而不是后台进程(据我所知)。

对于Fragments:

getActivity().runOnUiThread(new Runnable() 
{
    public void run() 
    {
        // Send Toast
        Toast.makeText(getActivity(), "Your Message!", Toast.LENGTH_SHORT).show();
    }
});

针对Activity:

this.runOnUiThread(new Runnable() 
{
    public void run() 
    {
        // Send Toast
        Toast.makeText(this, "Your Message!", Toast.LENGTH_SHORT).show();
    }
});

两者之间的区别仅在于您是调用this还是getActivity()来运行线程。无论哪种方式,它们都会在正在运行的活动上创建一个新线程。
希望这有所帮助!
哦,还要注意,在AsyncTask中,可以创建自己的函数,例如:
protected void myTaskFunction() throws exception
{ 
    // Stuff to do 
}

在您的AsyncTask类中的这些函数中,这就是您应该放置runOnUiThread()代码的位置。希望这样更加清晰易懂。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接