4

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

}

4

5 回答 5

4

到目前为止建议的所有其他答案都将起作用。但是,我要添加其他一些注释:

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

像这样的东西:

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

}

于 2012-11-12T16:58:34.307 回答
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;
    }
    ...
}
于 2012-11-12T16:58:10.093 回答
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

于 2012-11-12T16:41:48.697 回答
1

尝试使文本视图类级变量。

private TextView tv;

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

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

于 2012-11-12T16:42:07.703 回答
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" });
          }
}
于 2012-11-12T16:41:56.363 回答