【问题标题】:android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.android.view.ViewRoot$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸其视图。
【发布时间】:2014-08-04 19:54:56
【问题描述】:

我正在开发一个 android 应用程序,我需要在从服务器下载图像后显示图像,并且在下载进行时会显示一个进度对话框。为此,我使用了 asynctask 类。 我正在使用以下源代码。

           private void startDownload() {

    new DownloadFileAsync().execute(imageUrl);
    image.setImageBitmap(bitmap);
}
 @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case DIALOG_DOWNLOAD_PROGRESS:
                dialog = new ProgressDialog(this);
                dialog.setTitle("Loading");
                dialog.setMessage("Please wait...");
                dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                dialog.setCancelable(false);
                dialog.show();
                return dialog;
            default:
                return null;
        }
    }


 class DownloadFileAsync extends AsyncTask<String, String, String> {
     int count;
     URL myFileUrl;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showDialog(DIALOG_DOWNLOAD_PROGRESS);
        }

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


            try {
                myFileUrl = new URL(imageUrl);
                HttpURLConnection conn = (HttpURLConnection) myFileUrl
                        .openConnection();
                int lenghtOfFile = conn.getContentLength();
                //conn.setDoInput(true);
                conn.setConnectTimeout(10000);
                conn.setReadTimeout(10000);
                conn.connect();
                InputStream is = conn.getInputStream();
                bmImg = BitmapFactory.decodeStream(is);
                bitmap = BitmapFactory.decodeStream((InputStream) new URL(imageUrl)
                        .getContent());
                bitmap = Bitmap.createScaledBitmap(bitmap, 70, 70, true);

                  byte data[] = new byte[1024];
                  System.out.println("mmmmmmmmmmmm");

                    long total = 0;
                    System.out.println("nnnnnnnnnn");
                    while ((count = ((InputStream) new URL(imageUrl)
                    .getContent()).read(data)) != -1) {
                        total += count;
                        publishProgress(""+(int)((total*100)/lenghtOfFile));
                        for(int l=0;l<4;l++){
                        if(listObject.get(l).getImage()!="")
                       image.setImageBitmap(bitmap);
                    }}

            }
            catch(Exception e){
                System.out.println(e);}

        return null;
        }

        protected void onProgressUpdate(String... progress) {
            dialog.setProgress(Integer.parseInt(progress[0]));
        }

        @Override
        protected void onPostExecute(String unused) {
            image.setImageBitmap(bitmap);
            dismissDialog(DIALOG_DOWNLOAD_PROGRESS);

        }
        }

但它给出了以下异常:

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 

我无法找出问题所在。谁能帮我解决这个问题。 谢谢

【问题讨论】:

    标签: android progressdialog


    【解决方案1】:

    这是你的问题:

    for(int l=0;l<4;l++){
        if(listObject.get(l).getImage()!="")
            image.setImageBitmap(bitmap);
    }
    

    简短的回答:就像异常所说的那样,您试图在错误的线程中操作视图。在正确的线程(UI 线程)中执行。

    长答案:在 AsyncTask 中,进行视图操作的正确位置通常是 onPreExecuteonProgressUpdateonPostExecutedoInBackground 通常不是修改视图的好地方。您可以以多种方式之一回调 UI 线程(例如,您可以使用 post)。但是,您发布的那段代码对我来说并没有太大意义,而且您没有提供足够的上下文来解释它是什么,listObject 是什么等等。

    你还有一些其他的问题。你似乎试图以两种不同的方式连续两次读取数据......另外,我想你的while 条件会给你带来问题,因为你正在重新创建 URL 对象,只要你得到内容回来你会继续这样做。假设该 URL 没有动态内容,您将有一个无限循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-21
      • 1970-01-01
      • 1970-01-01
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      相关资源
      最近更新 更多