4

私はアンドロイドを始めたばかりで、htmlファイルのコンテンツをダウンロードする必要がある単純なアプリに取り組んでいます。提案どおり AsyncTask を使用していますが、1 つの問題が発生しています。次のコード (チュートリアル コードに従っています) ではtv cannot be resolvedonPostExecuteメソッドを取得します。ダウンロードしたファイルにアクセスするには?ありがとうございました:

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. tvこの onCreate 内の TextView と DownloadPage アクティビティのみにアクセスしている場合はtv、DownloadPage のコンストラクターに直接渡すことでアクセスを制限できます。
  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

1つのアプローチは、他の回答が示唆するように実行し、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);                
}

もう1つのオプションは、AsyncTaskを匿名で宣言し、タスクの宣言と同じメソッド本体でTextViewをfinalとして宣言することです。乾杯

于 2012-11-12T16:42:07.703 に答える
0

サブクラスからテレビにアクセスできるようにするには、テレビをフィールドにする必要があります。

    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 に答える