【问题标题】:Android: Crashing when trying to download images with an AsyncTask and JSONAndroid:尝试使用 AsyncTask 和 JSON 下载图像时崩溃
【发布时间】:2014-02-27 23:00:53
【问题描述】:

在我的 doInBackground 方法中,我试图创建一个 HTTPGet 并创建一个 JSONResponseHandler,而不是将它们都传递给 mClient.execute()。应用程序在 doInBackgroundMethod 中崩溃。任何帮助都会很棒。而且我对 Android 还很陌生,这可以解释我在这里的一些编码实践。这是我的代码:

public class Downloader extends AsyncTask <String, Void, List<Bitmap>>{

private static final String URL = "http://......";

private MainActivity mParentActivity;
private Context mApplicationContext;

AndroidHttpClient mClient = AndroidHttpClient.newInstance("");

// Constructor
    public Downloader(MainActivity parentActivity) {
        super();

        mParentActivity = parentActivity;
        mApplicationContext = parentActivity.getApplicationContext();

    }


@Override
protected List<Bitmap> doInBackground(String... params) {

    log("Entered doInBackground()");
    HttpGet request = new HttpGet(URL);
    JSONResponseHandler responseHandler = new JSONResponseHandler();

    try {
        return mClient.execute(request, responseHandler);
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;


}

@Override
protected void onPostExecute(List<Bitmap> result)
{
    mParentActivity.setImages(result);

}

private void log(String msg)
{
    Log.i(TAG, msg);
}

private class JSONResponseHandler implements ResponseHandler<List<Bitmap>> {

    private static final String IMAGE = "cover";
    private static final String LIST = "data";

    @Override
    public List<Bitmap> handleResponse(HttpResponse response)
            throws ClientProtocolException, IOException {
        List<Bitmap> result = new ArrayList<Bitmap>();
        String JSONResponse = new BasicResponseHandler()
                .handleResponse(response);
        try {

            // Get top-level JSON Object - a Map
            JSONObject responseObject = (JSONObject) new JSONTokener(
                    JSONResponse).nextValue();

            // Extract value of "Data" key -- a List
            JSONArray images = responseObject
                    .getJSONArray(LIST);

            InputStream is = null;

            // Iterate over data list
            for (int idx = 0; idx < images.length(); idx++) {

                // Get single piece of data - a Map
                JSONObject image = (JSONObject) images.get(idx);

                // open the url
                URL coverURL = (java.net.URL) image.get(IMAGE);
                HttpURLConnection conn = (HttpURLConnection) coverURL.openConnection();
                conn.setReadTimeout(10000 /* milliseconds */);
                conn.setConnectTimeout(15000 /* milliseconds */);
                conn.setRequestMethod("GET");
                conn.setDoInput(true);
                // Starts the query
                conn.connect();
                int r = conn.getResponseCode();
                Log.d(TAG, "The response is: " + r);
                is = conn.getInputStream();

                // creates an image from the inputStream
                Bitmap imageMap = BitmapFactory.decodeStream(is);


            result.add(imageMap);

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return result;
    }
}
}  

我的LogCat如下:

02-27 21:37:32.540: E/AndroidRuntime(1536): FATAL EXCEPTION: AsyncTask #1
02-27 21:37:32.540: E/AndroidRuntime(1536): Process: com.example.test, PID: 1536
02-27 21:37:32.540: E/AndroidRuntime(1536): java.lang.RuntimeException: An error occured   while executing doInBackground()
02-27 21:37:32.540: E/AndroidRuntime(1536):     at android.os.AsyncTask$3.done(AsyncTask.java:300)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at java.util.concurrent.FutureTask.run(FutureTask.java:242)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at java.lang.Thread.run(Thread.java:841)
02-27 21:37:32.540: E/AndroidRuntime(1536): Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.net.URL
02-27 21:37:32.540: E/AndroidRuntime(1536):     at com.example.test.DownloadStories$JSONResponseHandler.handleResponse(DownloadStories.java:109)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at com.example.test.DownloadStories$JSONResponseHandler.handleResponse(DownloadStories.java:1)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:657)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:627)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:616)
02-27 21:37:32.540: E/AndroidRuntime(1536):     at android.net.http.AndroidHttpClient.execute(AndroidHttpClient.java:273)

【问题讨论】:

  • 显示 logcat 输出...
  • 请添加有问题的日志以获得更多帮助

标签: java android json android-asynctask download


【解决方案1】:

将下面的行添加到您的下载器构造函数中,

mClient = AndroidHttpClient.newInstance("", mApplicationContext);

我认为您必须传递上下文才能获取实例。

【讨论】:

    【解决方案2】:

    我相信您的代码正在崩溃,因为它在这一行中内存不足

     Bitmap imageMap = BitmapFactory.decodeStream(is);
    
    
            result.add(imageMap);
    

    但我无法理解的是,您为什么不在该步骤中将图片保存到特定位置并释放内存

          void downloadFile(String fileUrl, String fileName) {
        URL myFileUrl = null;
        try {
            myFileUrl = new URL(fileUrl);
            HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
    
            if (bmImg != null) {
                bmImg.recycle();
            }
    
            bmImg = BitmapFactory.decodeStream(is);
            FileOutputStream out = new FileOutputStream(path + "/" + fileName + ".jpg");
            bmImg.compress(Bitmap.CompressFormat.JPEG, 50, out);
    
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            // Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }
    

    因此,通过此步骤,您无需创建 List&lt;Bitmap&gt;,我假设这是应用程序崩溃的原因

    【讨论】:

      【解决方案3】:

      在日志中:

      权限被拒绝(缺少 INTERNET 权限?

      AndroidManifest 中添加INTERNET 权限为:

      <uses-permission android:name="android.permission.INTERNET" /> 
      

      【讨论】:

      • 这是一个愚蠢的错误...我更新了该错误修复,但仍然出现错误。我已经更新了上面的 logcat 消息以反映新的错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多