2011-09-11 19 views
0

私はユーザーがビジネスの名前を入力できるEditTextを持っています。また、私は今、ユーザーの種類として、私は、データベースに、彼らは入力されたキーワードをチェックし、何それを取得し、すでにデータベースに追加されるかについて、ユーザーを提案し、こののEditText以下のListView ...Android効率的なAsyncTask

<EditText android:id="@+id/txtBusinessName" android:hint="Name of Business" /> 
<ListView android:id="@+id/suggestionList" 
    android:layout_width="fill_parent" android:layout_height="wrap_content"> 
</ListView> 

を持っていますリストビューでユーザーを表示する必要があります。イベントが発生し、すべてのキーまでに、私はこのように新しいAsyncTaskを呼び出しています現在...

 EditText txtBusinessName = (EditText) findViewById(R.id.txtBusinessName); 
       txtBusinessName.setOnKeyListener(new View.OnKeyListener() { 
        @Override 
        public boolean onKey(View v, int keyCode, KeyEvent event) { 
         if (event.getAction() == KeyEvent.ACTION_UP) { 
          if (v instanceof EditText) { 
           EditText txtBusinessName = ((EditText) v); 

           if (txtBusinessName.length() > 0) { 
            if (suggestionTask != null) { 
            suggestionTask.cancel(true); 
            suggestionTask = null; 
            } 
            suggestionTask = new GetCompaniesByKeywordAsyncTask(
             AddBusinessActivity.this, s); 
            suggestionTask.execute(txtBusinessName.getText() 
             .toString()); 
           } 
          } 
         } 
         return false; 
        } 
       }); 

は、私はちょうどAsyncTaskの単一のインスタンスを持っていると、ユーザーの種類として名を取得するためにそれを頼む方法はありますEditText?あまりにも多くのAsyncTaskを作成すると効率的でなく、例外的に終了するためです。名前を受け取った時点でListViewに値を設定しますが、ListViewにコンテンツの内容に基づいてサイズ変更を依頼できますか?

答えて

2

単一のAsyncTaskを作成するには、要求キューに基づいて実行するようにAsyncTaskを再構築する必要があります。キューには、処理するすべてのキーワードが含まれています。その後、このAsyncTaskをリスナーの外部で一度実行し、OnKeylistenerからキーワードを追加します。

は、リストビューを更新するために、我々は、doInBackground

あなたのコードがrouglyに変更された変更AsyncTaskその後


    @Override 
    protected Integer doInBackground(Void... params) { 
     int errorCode = 0; 

     try { 
      // while running in the context of your activity 
      // you should set this boolean to false once you have leave the activity 
      while(!isRunning){ 
       // blocking call to get the next keyword that is added to the queue 
       String responseData = getNextKeyword(); 

       // once you get the next keyword, you publish the progress 
       // this would be executed in the UI Thread and basically would update the ListView 
       publishProgress(responseData); 
      } 
     } catch(Exception e) { 
      // error handling code that assigns appropriate error code 
     } 

     return errorCode; 

    } 

    @Override 
    protected void onPostExecute(Integer errorCode) { 
     // handle error on UI Thread based on errorCode 
    } 

    @Override 
    protected void onProgressUpdate(String... values) { 
     String searchKeyword = values[0]; 

     // handle the searchKeyword here by updating the listView 
    } 

    /*** 
    * Stub code for illustration only 
    * Get the next keyword from the queue 
    * @return The next keyword in the BlockingQueue 
    */ 
    private String getNextKeyword() { 
     return null; 
    } 

    /*** 
    * Stub code for illustration only 
    * Add new keyword to the queue, this is called from the onKey method 
    * @param keyword 
    */ 
    public void addKeyword(String keyword) { 
     // add the keyword to the queue 
    } 

のスケルトンコードでの結果に基づいてリストビューを更新することonProgressUpdateを利用します。


// instantiate AsyncTask once 
suggestionTask = new GetCompaniesByKeywordAsyncTask(
     AddBusinessActivity.this, s); 

// run only one AsyncTask that is waiting for any keyword in the queue 
suggestionTask.execute(); 

EditText txtBusinessName = (EditText) findViewById(R.id.txtBusinessName); 
txtBusinessName.setOnKeyListener(new View.OnKeyListener() { 
    @Override 
    public boolean onKey(View v, int keyCode, KeyEvent event) { 
     if (event.getAction() == KeyEvent.ACTION_UP) { 
      if (v instanceof EditText) { 
       EditText txtBusinessName = ((EditText) v); 

       if (txtBusinessName.length() > 0) { 
        // add new keyword to the queue for processing 
        suggestionTask.addKeyword(txtBusinessName.getText() 
         .toString()); 
       } 
      } 
     } 
     return false; 
    } 
}); 
+0

AsyncTaskオブジェクトにキューコレクションを維持する必要がありますか? – Neutralizer

+0

AsyncTaskオブジェクトの外部でキューを使用するつもりがない場合は、AsyncTaskのインスタンス変数として保持するのが理にかなっています。キューの場合、[BlockingQueue](http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html)を利用してみてください。 – momo

+0

良い仕事。 ListViewが読み込まれたら、そのコンテンツに基づいてサイズを変更する方法を知っていますか? – Neutralizer