使用Android AsyncTask下载html文件

时间:2012-11-12 16:38:19

标签: android android-asynctask

我刚开始使用android,我正在开发一个应该下载html文件内容的简单应用程序。我按照建议使用AsyncTask,但我遇到了一个问题。在下面的代码中(我遵循教程代码),我得到了tv cannot be resolved方法onPostExecute。如何访问下载的文件?谢谢你:

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" });
      }

}

5 个答案:

答案 0 :(得分:4)

到目前为止建议的所有其他答案都有效。但是,我还会添加其他一些注释:

  1. 如果您只访问此onCreate和DownloadPage活动中的TextView tv,则可以通过直接将其提供给DownloadPage的构造函数来限制对tv的访问
  2. 对于像DownloadPage AsyncTask这样有用的东西,我通常将它从任何活动的内部类中删除,而是将其放在一个名为“Utils”的公共类中,可以根据需要由许多其他活动使用。 (代码模块化)
  3. 如果您打算使用内部课程(完全合法),那么将privatestatic作为您所做的事情总是好的做法。
  4. 这样的事情:

    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);
                }
            }
        }
    }
    

    }

答案 1 :(得分:3)

一种方法是按照其他答案的建议做,并使tv实例级别。或者,您可以在TextView中创建AsyncTask字段,并将引用传递给构造函数:

...
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;
    }
    ...
}

答案 2 :(得分:1)

如果要在方法之外访问变量,则需要在方法外部声明它。这是一个称为范围的基本编程概念。

将您的代码更改为:

public class FlashResults extends Activity {
private TextView tv;

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

它将可用于FlashResults内的任何内容。

答案 3 :(得分:1)

尝试制作文本视图类级变量。

private TextView tv;

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

另一个选项是声明您的AsyncTask是匿名的,在与您的任务声明相同的方法体中将TextView声明为final。 干杯

答案 4 :(得分:0)

你必须让tv成为一个字段才能从子类中访问它。

    public class FlashResults extends Activity {

      TextView tv;

      @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            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" });
          }
}