Android эффективный AsyncTask - PullRequest
       5

Android эффективный AsyncTask

0 голосов
/ 11 сентября 2011

У меня есть EditText, где пользователь может ввести название компании.У меня также есть ListView ниже этого EditText, который предлагает пользователю информацию о том, что уже добавлено в базу данных ...

<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>

Теперь, когда пользователь вводит, я проверяю введенное им ключевое слово в базе данных и получаючто он должен показать пользователю в ListView.В настоящее время при каждом событии key up, я вызываю новый 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 изменить свой размер в зависимости от содержимого внутри него?

1 Ответ

2 голосов
/ 11 сентября 2011

Чтобы создать единый AsyncTask, вам необходимо реструктурировать AsyncTask для запуска на основе очереди запросов. Очередь содержит все ключевые слова, которые вы хотите обработать. Затем вы должны запустить этот AsyncTask за пределами слушателя и добавить ключевое слово из OnKeylistener.

Чтобы обновить ListView, мы будем использовать onProgressUpdate, который обновит ListView на основе результата в doInBackground

Скелетный код для модификации 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
    }

Тогда ваш код будет изменен на:


// 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;
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...