Android - 将字符串传递给Asynctask?

时间:2013-02-28 19:34:19

标签: android string android-asynctask parameter-passing

与我之前关于ANR问题的问题(Android - Strings.xml versus text files. Which is faster?)相关。

我按照受访者的建议尝试使用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的东西应该在post执行时完成。 如果是这种情况,我应该在doInBackground()部分返回什么,然后传递onPostExecute()?

(非常感谢大家!我现在已经接近正常工作了!)

2 个答案:

答案 0 :(得分: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()中,但您需要将TextView的引用传递给AsyncTask。您可以从String传回要设置文字的onPostExecute(),并将其设置在Activity中。希望这有帮助

答案 1 :(得分:1)

  1. 为您的AsyncTaskRunner课程创建构造函数。
  2. Context(您的活动上下文)和databaseOutput TextView作为参数传递给您的AsyncTaskRunner类构造函数。
  3. AsyncTaskRunner中保存对这两个对象的引用。
  4. enhancedStem传递给execute()方法。
  5. 使用传递给构造函数的Context作为ProgessDialog.show()的第一个参数
  6. 您无法从databaseOutput方法访问doInBackground()。您必须只能在UI线程上运行的onPostExecute()中访问它。因此,使用您传递给构造函数的databseOutput引用来相应地更新onPostExecute()方法中的TextView。
  7. 作为备注,您可以使用doInBackground()方法返回的任何内容作为onPostExecute()方法的参数。

    请参阅http://developer.android.com/reference/android/os/AsyncTask.html

    我建议您传递所需的数据,而不是使用封闭的类访问它 - 这会使您的ASyncTaskRunner更加灵活,通常是更好的做法。