我制作了一段代码,假设使用 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();
}