【问题标题】:Android Waiting progress bar Can't create handler inside thread that has not called Looper.prepare() errorAndroid Waiting progress bar Can't create handler inside the thread that has not called Looper.prepare() 错误
【发布时间】:2013-02-26 09:00:47
【问题描述】:

在我的 android 应用程序中,我将一些数据从服务器数据库复制到本地数据库。这可能需要 15 分钟以上。对于较慢的连接,它可能会被超过。所以我想显示一个等待进度条。

代码贴在下面。

refresh.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
final ProgressDialog progressDialog = ProgressDialog.show(login.this, "", "Please wait...");
new Thread() {
public void run() {
try{
mySQLiteAdapter.openToWrite();
mySQLiteAdapter.deleteAll();
radapter.openToWrite();
radapter.deleteAll();
uadapter.openToWrite();
uadapter.deleteAll();
        try
            {
                 HttpClient httpclient = new DefaultHttpClient();
                 HttpPost httppost = new HttpPost("http://xxxxxxxxxxxxxxxxxxxxx");
                 HttpResponse response = httpclient.execute(httppost);
                 HttpEntity entity = response.getEntity();
                  is = entity.getContent();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        is, "iso-8859-1"), 8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
                is.close();
                json = sb.toString();
            } catch (Exception e) {
            Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
            }

            try {
                jObj = new JSONObject(json);
                contacts = jObj.getJSONArray("get");
                for(int i = 0; i < contacts.length(); i++){
                JSONObject c = contacts.getJSONObject(i);
                    if(!c.isNull("rname"))// || c.getString("rcode").equals(null))
                    {
                        rname = c.getString("rname");
                        rcode = c.getString("rcode");
                        radapter.insert(rcode, rname);
                    }
                    else
                    {
                        rname = "";
                        rcode = c.getString("rcode");
                        radapter.insert(rcode, rname);
                    }
                }
                Toast.makeText(getBaseContext(), " Ryot BackUp completed", Toast.LENGTH_SHORT).show();

            } catch (JSONException e) {
                Toast.makeText(getBaseContext(), "Error"+e.toString(), Toast.LENGTH_LONG).show();
            }
                   progressDialog.dismiss();
               }
            }.start();
            adapter.deleteAll();
            oadapter.deleteAll();
            e2.setText("Back Up completed");
        }
            catch (Exception e) {
               Log.e("tag", e.getMessage());
               }
                   progressDialog.dismiss();
               }
            }.start();
       }

   });

当我运行我的应用程序时,进度条只显示几秒钟,然后执行 Catch 块,显示 logcat 错误为

Logcat:

02-26 14:26:07.151: E/tag(301): Can't create handler inside thread that has not called Looper.prepare()

谁能解释我的代码中的错误以及如何解决它

【问题讨论】:

  • 尝试从另一个线程访问 ui 的典型案例。解决方案是使用异步任务处理后台内容并在 onProgressUpdate 和 onPostExecute 中访问 ui。

标签: android multithreading progress-bar progressdialog


【解决方案1】:
Toast.makeText(getBaseContext(), " Ryot BackUp completed", Toast.LENGTH_SHORT).show();

问题是由上面的代码引起的,这个方法会改变UI,你不能在非ui线程中更新UI。所以你需要从主 ui 线程调用它。

由于这是一项耗时的工作,我强烈建议您在 Android 中使用AsyncTask

但如果你只想对现有代码做一点改动,尝试使用

context.runOnUiThread(new Runnable() {
  public void run() {
    Toast.makeText(...).show();
  }
});

或者handler,你可以看看How Handler Work in Android。一个基本的例子:

public Handler mHandler = new Handler() {

    public void handleMessage(Message msg) {
           //show toast here
    }
}

protected void startLongRunningOperation() {

    Thread t = new Thread() {
        public void run() {
            //do something here
            //update the result
            mHandler.postDelayed(mUpdateResults, 200);}
            mHandler.post(mUpdateResults);
        }
    };
    t.start();
}

【讨论】:

  • 我应该在哪里使用它?仅用于显示吐司
【解决方案2】:

不要创建一个新线程,而是创建一个 HandlerThread - http://developer.android.com/reference/android/os/HandlerThread.html

只需将“new Thread()”替换为“new HandlerThread(“any string”)”就可以了。

【讨论】:

    猜你喜欢
    • 2013-12-27
    • 2019-08-28
    • 2011-10-07
    • 2023-03-18
    • 2013-05-04
    • 1970-01-01
    • 2021-09-28
    • 2022-11-17
    • 1970-01-01
    相关资源
    最近更新 更多