使用AsyncTask下载图像(URL)



我制作了一段代码,假设使用 url 从互联网下载图像并显示它ImageView问题是我收到空指针异常并且我找不到问题

这是活动中的代码片段

public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btnShow:
        DownloadImageTask download=new DownloadImageTask(this);
        String imageUrl = ((EditText) findViewById(R.id.editUrl)).getText().toString(); 
        download.execute(imageUrl); 
        break;
    }
}

这是异步任务代码

public class DownloadImageTask extends AsyncTask<String, Integer, Bitmap> {
    private Activity mActivity;  
    private ProgressDialog mDialog;

    public DownloadImageTask(Activity mActivity) {
        super();
        this.mActivity = mActivity;
    }
    protected void onPreExecute() {
        ImageView imageView = (ImageView) mActivity.findViewById(R.id.imageView1);
        imageView.setImageBitmap(null);
        mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mDialog.setCancelable(true);
        mDialog.setMessage("Loading...");
        mDialog.setProgress(0);       
    }
    protected Bitmap doInBackground(String... urls) {
        Log.d("doInBackground", "starting download of image");        
        Bitmap image = downloadImage(urls[0]);
        return image;
    } 
    protected void onProgressUpdate(Integer... progress) {   
        mDialog.show();
        mDialog.setProgress(progress[0]);        
    }
    protected void onPostExecute(Bitmap result) {
        if (result != null) {            
            ImageView imageView = (ImageView) mActivity.findViewById(R.id.imageView1);
            imageView.setImageBitmap(result);
        }
        else {
        }
        mDialog.dismiss();
    }
    private Bitmap downloadImage(String urlString) {
        URL url;        
        try {
            url = new URL(urlString);
            HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();          
            InputStream is = httpCon.getInputStream();          
            int fileLength = httpCon.getContentLength();
            mDialog.setMax(fileLength);
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int nRead, totalBytesRead = 0;          
            byte[] data = new byte[2048];
            while ((nRead = is.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, nRead);
                totalBytesRead += nRead;                
                publishProgress(totalBytesRead);               
            }          
            byte[] image = buffer.toByteArray();             
            Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);             
            return bitmap;
        } catch (Exception e) {            
            e.printStackTrace();
        }     
        return null;
    }
}

那是日志猫错误

12-17 16:15:33.938: E/AndroidRuntime(29324): FATAL EXCEPTION: main
12-17 16:15:33.938: E/AndroidRuntime(29324): Process: com.example.movieandroidproject, PID: 29324
12-17 16:15:33.938: E/AndroidRuntime(29324): java.lang.NullPointerException
12-17 16:15:33.938: E/AndroidRuntime(29324):    at com.example.asyncTask.DownloadImageTask.onPreExecute(DownloadImageTask.java:30)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at android.os.AsyncTask.execute(AsyncTask.java:535)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at com.example.movieandroidproject.ChooseMovieAdd.onClick(ChooseMovieAdd.java:89)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at android.view.View.performClick(View.java:4461)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at android.view.View$PerformClick.run(View.java:18525)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at android.os.Handler.handleCallback(Handler.java:733)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at android.os.Handler.dispatchMessage(Handler.java:95)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at android.os.Looper.loop(Looper.java:136)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at android.app.ActivityThread.main(ActivityThread.java:5118)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at java.lang.reflect.Method.invokeNative(Native Method)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at java.lang.reflect.Method.invoke(Method.java:515)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:610)
12-17 16:15:33.938: E/AndroidRuntime(29324):    at dalvik.system.NativeStart.main(Native Method)

首先,您应该关闭输入流。

buffer.close();
is.close();

您应该检查此处是否抛出并捕获了任何异常,因为您在函数末尾返回 null。

try {
        url = new URL(urlString);
        HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();          
        InputStream is = httpCon.getInputStream();          
        int fileLength = httpCon.getContentLength();
        mDialog.setMax(fileLength);
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead, totalBytesRead = 0;          
        byte[] data = new byte[2048];
        while ((nRead = is.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
            totalBytesRead += nRead;                
            publishProgress(totalBytesRead);               
        }          
        byte[] image = buffer.toByteArray();             
        Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);             
        return bitmap;
    } catch (Exception e) { 
        // here           
        e.printStackTrace();
    }  
调用时未

初始化 mDialog 字段

    mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
public DownloadImageTask(Activity mActivity) {
    super();
    this.mActivity = mActivity;
    this.mDialog = new ProgressDialog(this);
}

但这是不好的解决方案。至于我,最好是在活动中创建showProgress和hideProgress方法,并在任务中在OnPreExecute和onPostExecute中调用它们。

我认为问题不在于AsyncTask,而在于进度条。您尚未初始化它:

mProgress = (ProgressBar) findViewById(R.id.progress_bar);   // This line is missing...

您可以像这样简化用于下载图像的方法

public Bitmap downloadImage(String src){
        try {
            URL url = new URL(src);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream inputStream = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(inputStream);
            return  myBitmap;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

然后你像这样使用它:

protected Bitmap doInBackground(String... urls) {
        Log.d("doInBackground", "starting download of image");        
        Bitmap image = downloadImage(urls[0]);
        return image;
    } 
    protected void onProgressUpdate(Integer... progress) {   
        mDialog.show();
        mDialog.setProgress(progress[0]);        
    }
    protected void onPostExecute(Bitmap result) {
        if (result != null) {            
            ImageView imageView = (ImageView) mActivity.findViewById(R.id.imageView1);
            imageView.setImageBitmap(result);
        }
        else {
        }
        mDialog.dismiss();
    }

最新更新