1

I have an app that loads images into bitmaps using a URL and recently got an email from a user with Android 2.2.1 who has been having trouble with some images not loading. I've tried looking around and can't seem to find any connection between the images that don't load. Furthermore, sometimes images that wouldn't load for her will start working again like nothing was wrong. I've never heard of this problem with any later versions of Android, so I would think it's an issue specific to 2.2.1. If anyone can explain to me what's going wrong and (if possible) how to fix it I would really appreciate it.

Here is the relevant code:

public class htmlGrabber extends AsyncTask<String, Void, String>{

        @Override
        protected String doInBackground(String... params) {
             try {
                    return getHtml();
                } 
                catch (IOException e) {
                    problem();
                    return null;
                }
        }//end of doInBackground

        @Override
        protected void onPostExecute(String result){
                Loading.fa.finish();
                shared_preferences=getSharedPreferences("shared_preferences_test", MODE_PRIVATE);
                shared_preferences_editor = shared_preferences.edit();
                shared_preferences_editor.putString("url_key", current);
                shared_preferences_editor.commit();
                TouchImageView img = (TouchImageView) findViewById(R.id.img);
                img.setImageBitmap(bitmap);
            }
        }

    public String getHtml() throws IllegalStateException, IOException{
        //gets html from the url stored in current, then parses through it and extracts the image url, then converts 
        //it into a bitmap image
        String html = "";

            HttpClient client = new DefaultHttpClient();
            HttpGet request = new HttpGet(current);
            HttpResponse response = client.execute(request);
            InputStream in = response.getEntity().getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder str = new StringBuilder();
            String line = null;
            while((line = reader.readLine()) != null)
            {
                str.append(line);
            }
            in.close();
            html = str.toString();

            /* Edited out the code that parses through the HTML looking for the image URL. The image URL is stored in the string "link"

            try {
                bitmap = BitmapFactory.decodeStream((InputStream)new URL(link).getContent());
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        return html;
    }//end of getHtml


}//end of htmlGrabber

If you need anything clarified please let me know!

CheeseCoder
  • 701
  • 1
  • 7
  • 11

1 Answers1

1

when you try with an android 2.2.1 you get this problem as well? when exactly?

because if this AsyncTask is lunched by an activity, than it depends of this Activity (if you change the orientation or whatever, the task will be killed and lunched again) , and may be this behavior is not working well in her phone ... and it would be better to think about caching the pictures ...

you can as well see this question which is explaining more the problem with AsyncTask definition in Android, and how many times this definition has been changed; so it's normal that it is not working the same way in every version. In the documentation they say:

When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting HONEYCOMB, tasks are back to being executed on a single thread to avoid common application errors caused by parallel execution. If you truly want parallel execution, you can use the executeOnExecutor(Executor, Params...) version of this method with THREAD_POOL_EXECUTOR; however, see commentary there for warnings on its use. Both executeOnExecutor() and THREAD_POOL_EXECUTOR are Added in API level 11 (Android 3.0.x, HONEYCOMB).

--> This means that if you create two AsyncTasks to download two files, the 2nd download will not start until the first one finishes. If you chat via two servers, and the first server is down, you will not connect to the second one before the connection to the first one times out. (Unless you use the new API11 features, of course, but this will make your code incompatible with 2.x).

And if you want to target both 2.x and 3.0+, the stuff becomes really tricky.

I propose for exemple universal image loader which is a good, "famous" and really easy API for loading pictures and handling automatically the cache ...

Actually, I am using the Universal Image Loader; the solution is not related to the fact of caching, but to the fact that the instance of this Loader is not related to the context of the activity (its methods are related but by caching they handle the lifecycle of the activity), that means that your task will not be totally killed and restarted by the onDestroy() of the Activity. you can open an instance of it and you use its methods for all the application. When you want to kill this instance you call its own Destroy.

I can't say, if this will resolve your problem for sure. I don't think you will be able to answer to this without testing, too... but may be it will solve other problems...

I hope I helped ...

Community
  • 1
  • 1
ahmed_khan_89
  • 2,755
  • 26
  • 49
  • Since I don't have physical access to the device I don't know when any sort of errors occur (can't even look at the logcat). The Async is being launched by an activity and the activity is not changed (rotated, etc) during this time, which led me to believe it was a problem with 2.2.1 and Async. So you're saying that Async could be working differently in version 2.x than in 3.x. Would caching the pictures help remedy this problem or is the best solution for them to upgrade their version of android? Thanks for the reply! – CheeseCoder Apr 06 '14 at 22:19
  • I updated my answer, in order to clarify and answer your question. Briefly, this Loader instance is independent of the Context of the activity. – ahmed_khan_89 Apr 06 '14 at 23:17
  • So what you're saying is that by applying Universal Image Loader and caching, the AsyncTask will not be tied to any particular activity and will always be running in the background until manually killed. While running, any activity can access it's methods and said activity can be destroyed without destroying the AsyncTask? – CheeseCoder Apr 07 '14 at 20:14
  • kind of that; can be paused/restarted but not killed. I hope I helped – ahmed_khan_89 Apr 07 '14 at 22:49
  • 1
    Yes, you have been extremely helpful in helping me understand this problem! Furthermore, Universal Image Loader will also be very useful for me since I've been meaning to set up a cache for the images. Thank you so much for your help! – CheeseCoder Apr 08 '14 at 16:56