有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在AsyncTask的doInBackground()方法中运行FileOutputStream操作的java无法成功执行

我使用AsyncTask作为内部类来保存位图。但是FileOutputStream操作不起作用。如果我在UI线程的方法中运行相同的代码,代码就会运行,并且我能够成功地保存位图

我知道doInBackground()方法会执行,onPostExecute()方法也会执行

此外,如果我获取传递给AsyncTask的输入流,并尝试对其进行解码以设置imageView,则它不会工作。但如果我在AsyncTask之外使用相同的代码,它就会工作

我按如下方式实现了AsyncTask,第2和第3条日志语句没有被记录,所以我知道有些东西运行不正常:

public class SaveImageToInternalStorage extends AsyncTask {

    InputStream bitmap;
    String PICTURE_KEY;

    public SaveImageToInternalStorage1(final InputStream bitmap, final String PICTURE_KEY) {
        this.bitmap = bitmap;
        this.PICTURE_KEY = PICTURE_KEY;



      }


        @Override
        protected Object doInBackground(Object[] params) {
            FileOutputStream fos;
            try {

                fos =  picture_chooser.this.openFileOutput(PICTURE_KEY, MODE_PRIVATE);

              Bitmap bitmap2 = BitmapFactory.decodeStream(bitmap);
                Log.v("saveBitmap", " first log statement");  ////This gets logged
                bitmap2.compress(Bitmap.CompressFormat.WEBP, 85, fos);
                 Log.v("saveBitmap", " second log statement");  // This is not logged
                fos.close();

              Log.v("saveBitmap", " third log statement"); // This is not logged
            } catch (Exception e) {
                Log.e("saveToInternalStorage()", e.getMessage());

            }

            return null;
        }


        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
   Log.v("saveBitmap", " onPostExecute log statement");  // This is logged
            imageViewSetter(bitmap);

        }
    }


    //runs in the wrapper class 
      public void imageViewSetter(InputStream inputStream) {
            imageView.setImageBitmap(BitmapFactory.decodeStream(inputStream)); //this does not set the imageView 

        }

任何帮助都将不胜感激


共 (1) 个答案

  1. # 1 楼答案

    从Android参考here中看一看这个例子

    我已经在下面为您重新创建了代码

     private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }
    
     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }
    
     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
    }
    

    注意,顶部的类声明后面是

    <URL, Integer, Long> 
    

    接下来,看看类中三个重写的方法。您会注意到,URL指的是传递给doInBackground的参数,Integer指的是onProgressUpdate输出的参数,Long指的是doInBackground方法返回给onPostExecute的参数

    从这里,您有望看到AsyncTask的用法如下

    doInBackground把你想做的任何事情都交上来。此方法在后台线程上完成所需的工作。此方法需要将完成的对象返回到onPostExecute,在那里可以捕获完成的工作的结果,并在需要时更新UI。 onProgressUpdate是可选的,您不需要在这里执行任何操作