1

与我之前关于 ANR 问题的问题有关(Android - Strings.xml 与文本文件。哪个更快?)。

我尝试按照受访者的建议使用 AsyncTask,但我现在不知所措。

我需要将一个字符串从我的菜单活动传递给 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);
}

这是异步部分:已更新

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类或类中的其他方法之一中进行更改,Async例如onPostExecute()它是否是内部类。否则,您可以将值传递回菜单活动以更新您的TextView

编辑

您仍在尝试使用此方法UI进行更改doInBackground()

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

然后当你打电话时setText()。这需要放入您的文件中onPostExecute(),但随后您需要将您的引用传递TextViewAsyncTask. 您可以将String您想要将文本设置为 from your 的内容传回并将其onPostExecute()设置在您的Activity. 希望这可以帮助

于 2013-02-28T19:41:00.033 回答
1
  1. AsyncTaskRunner为您的类创建一个构造函数。
  2. 将 a Context(您的活动上下文)和databaseOutput TextViewas 参数都传递给您的AsyncTaskRunner类构造函数。
  3. 将这两个对象的引用保存在AsyncTaskRunner.
  4. 传递enhancedStemexecute()方法。
  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 回答