1

ANRの問題に関する以前の質問に関連しています(Android-Strings.xmlとテキストファイル。どちらが速いですか?)。

回答者のアドバイスに従ってAsyncTaskを使用してみましたが、今は途方に暮れています。

メニューアクティビティから非同期タスクに文字列を渡す必要がありますが、それは本当に混乱します。私はすでに5時間検索と勉強をしていますが、それでもできません。

これが私のコードの抜粋です:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    /** Create an option menu from res/menu/items.xml */
    getMenuInflater().inflate(R.menu.items, menu);

    /** Get the action view of the menu item whose id is search */
    View v = (View) menu.findItem(R.id.search).getActionView();

    /** Get the edit text from the action view */
    final EditText txtSearch = ( EditText ) v.findViewById(R.id.txt_search);

    /** Setting an action listener */
    txtSearch.setOnEditorActionListener(new OnEditorActionListener() {

        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

            final EditText txtSearch = ( EditText ) v.findViewById(R.id.txt_search);
            String enhancedStem = txtSearch.getText().toString();
            TextView databaseOutput = (TextView)findViewById(R.id.textView8);

            new AsyncTaskRunner().execute();
            // should I put "enhancedStem" inside execute?
            }
          });
return super.onCreateOptionsMenu(menu);
}

これが非同期部分です:UPDATED

public class AsyncTaskRunner extends AsyncTask<String, String, String> {
      String curEnhancedStem;
      private ProgressDialog pdia;

      public AsyncTaskRunner (String enhancedStem)
      {
           this.curEnhancedStem = enhancedStem;
      }

      @Override
      protected void onPreExecute() {
       // Things to be done before execution of long running operation. For
       // example showing ProgessDialog
          super.onPreExecute();
          pdia = ProgressDialog.show(secondactivity.this, "" , "Searching for words");
      }



    @Override
    protected String doInBackground(String... params) {

        if(curEnhancedStem.startsWith("a"))
        {
            String[] wordA = getResources().getStringArray(R.array.DictionaryA);
            String delimiter = " - ";
            String[] del;
            TextView databaseOutput1 = (TextView)findViewById(R.id.textView8);
            for (int wordActr = 0; wordActr <= wordA.length - 1; wordActr++)
            {
                String wordString = wordA[wordActr].toString();
                del = wordString.split(delimiter);

                if (curEnhancedStem.equals(del[0]))
                {
                    databaseOutput1.setText(wordA[wordActr]);
                    pdia.dismiss();
                    break;
                }
                else
                    databaseOutput1.setText("Word not found!");
            }
        }

       return null;
      } 


      @Override
      protected void onProgressUpdate(String... text) {
       // Things to be done while execution of long running operation is in
       // progress. For example updating ProgessDialog

      }

      @Override
      protected void onPostExecute(String result) {
       // execution of result of Long time consuming operation
      }
}

取得が機能するようになりました。探している単語が表示されているのを見ましたが、突然終了しました。おそらく、あなたが言ったように、UIの処理は実行後に実行する必要があるためです。その場合、doInBackground()部分で何を返し、onPostExecute()を渡す必要がありますか?

(たくさんの人に感謝します!私は今、これを適切に機能させることに近づいています!)

4

2 に答える 2

3

それが問題です。それらは、それらを宣言したメソッドに対してローカルであり、それらにAsyncTaskアクセスできないクラスを宣言しています。AsyncTaskがメニューアクティビティの内部クラスである場合は、それらをメンバー変数として宣言できます。

public class MenuActivity extends Activity
{
     String enhancedStem;
     ....

別のクラスの場合は、クラスにコンストラクターを作成し、Asyncその変数をコンストラクターに渡すことができます。

public class AsyncTaskRunner extends AsyncTask<String, String, String> {
  String curEnhancedStem;
  private ProgressDialog pdia;

  public void AsyncTaskRunner (String variableName)
{
     this.curEnhancedStem = variableName;
}

そしてそれを次のように呼びます

 AsyncTaskRunner newTask = new AsyncTaskRunner(enhancedStem);
 newTask.execute();

また、何かを行うことはできないUIのでdoInBackground、これはクラス内で変更するか、内部クラスであるかどうかなど、クラスActivity内の他のメソッドの1つで変更する必要があります。それ以外の場合は、メニューアクティビティに値を戻して、AsynconPostExecute()TextView

編集

あなたはまだこれUIでインを変更しようとしていますdoInBackground()

TextView databaseOutput1 = (TextView)findViewById(R.id.textView8);

その後、もう一度呼び出しますsetText()。これはあなたに入れる必要がありますが、それからあなたはあなたのonPostExecute()参照をに渡す必要があります。テキストを自分から設定したいものを返して、に設定することができます。お役に立てればTextViewAsyncTaskStringonPostExecute()Activity

于 2013-02-28T19:41:00.033 に答える
1
  1. クラスのコンストラクターを作成しますAsyncTaskRunner
  2. Context(アクティビティコンテキスト)とdatabaseOutput TextViewas引数の両方をAsyncTaskRunnerクラスコンストラクターに渡します。
  3. これら2つのオブジェクトへの参照をに保存しますAsyncTaskRunner
  4. enhancedStemメソッドに渡しexecute()ます。
  5. Contextコンストラクターに渡したを最初の引数として使用しますProgessDialog.show()
  6. databaseOutputメソッドからアクセスすることはできませんdoInBackground()onPostExecute()UIスレッドで実行されるでのみアクセスする必要があります。したがって、databseOutputコンストラクターに渡した参照を使用して、それにonPostExecute()応じてメソッドのTextViewを更新します。

注意として、メソッドから返すものはすべて、doInBackground()メソッドのパラメーターとして使用できますonPostExecute()

http://developer.android.com/reference/android/os/AsyncTask.htmlを参照してください

囲んでいるクラスを使用してアクセスするのではなく、必要なデータを渡すことをお勧めします。これにより、ASyncTaskRunner柔軟性が大幅に向上し、一般的にはより適切な方法になります。

于 2013-02-28T19:46:08.487 に答える