Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Android AsyncTask to download html file

i just started with android and i'm working on a simple app that should download contents of a html file. I'm using AsyncTask as suggested, but i'm encountering one problem. In the following code (i followed a tutorial code), i get tv cannot be resolved for the onPostExecute method. How to access the downloaded file? Thank You:

public class FlashResults extends Activity {
  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        setContentView(tv);
        readWebpage(tv);                
  }


  protected class DownloadPage extends AsyncTask<String, Void, String> {
          protected String doInBackground(String... urls) {

          String responseStr = null;

          try {
              for (String url : urls) {   
              DefaultHttpClient httpClient = new DefaultHttpClient();
              HttpGet get = new HttpGet(url);
              HttpResponse httpResponse = httpClient.execute(get);
              HttpEntity httpEntity = httpResponse.getEntity();
              responseStr = EntityUtils.toString(httpEntity);
              } 
          } catch (UnsupportedEncodingException e) {

          } catch (ClientProtocolException e) {

          } catch (IOException e) {

          }
          return responseStr;
      }

      protected void onPostExecute(String result) {           
          tv.setText(result);
      }
  }

  public void readWebpage(View v) {
        DownloadPage task = new DownloadPage();
        task.execute(new String[] { "http://seznam.cz" });
      }

}

like image 926
Lukas Tomsu Avatar asked Jan 16 '23 01:01

Lukas Tomsu


2 Answers

All of the other answers suggested so far will work. However, I would add in a couple of other notes:

  1. if you are only accessing the TextView tv inside this onCreate and the DownloadPage acitivity, you can limit access to tv by giving it directly to the DownloadPage's constructor
  2. for something as useful as a DownloadPage AsyncTask, i usually remove it from being an inner class of any activity and instead put it in a public class called "Utils" that can be used by many other activities as needed. (modularity in code)
  3. if you are going to use an inner class (perfectly legal), it's always good practice to make it private and static for what you're doing.

Something like this:

public class FlashResults extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        setContentView(tv);
        readWebpage(tv);
    }

    public void readWebpage(View v) {
        DownloadPage task = new DownloadPage(tv);
        task.execute(new String[] { "http://seznam.cz" });
    }

    private static class DownloadPage extends AsyncTask<String, Void, String> {

        private TextView textView;
        public DownloadPage(TextView tv){
            textView = tv;
        }

        protected String doInBackground(String... urls) {

         String responseStr = null;

          try {
              for (String url : urls) {   
              DefaultHttpClient httpClient = new DefaultHttpClient();
              HttpGet get = new HttpGet(url);
              HttpResponse httpResponse = httpClient.execute(get);
              HttpEntity httpEntity = httpResponse.getEntity();
              responseStr = EntityUtils.toString(httpEntity);
              } 
          } catch (UnsupportedEncodingException e) {

          } catch (ClientProtocolException e) {

          } catch (IOException e) {

          }
            return responseStr;
        }

        protected void onPostExecute(String result) {           
            if (textView != null) {
                textView.setText(result);
            }
        }
    }
}

}

like image 184
David T. Avatar answered Jan 23 '23 21:01

David T.


One approach is to do as the other answers suggest and make tv instance level. Alternatively you can make a TextView field within your AsyncTask and pass a reference into the constructor:

...
public void readWebpage(TextView v) {
    DownloadPage task = new DownloadPage(v);
    task.execute(new String[] { "http://seznam.cz" });
}
...
protected class DownloadPage extends AsyncTask<String, Void, String> {
    protected String doInBackground(String... urls) {
        ...
    }
    TextView tv = null;

    public DownloadPage(TextView tv){
        this.tv = tv;
    }
    ...
}
like image 21
dave.c Avatar answered Jan 23 '23 22:01

dave.c