asynctask не получает arraylist при вызове из обработчика

Я использую обработчик для запуска асинхронной задачи, но при этом мое приложение падает. Причина, по которой я застрял, заключается в том, что если я запускаю асинхронную задачу через что-то еще (например, onClickListener), то я могу запускать ее столько раз, снова и снова, и она работает идеально каждый раз. Как только я выполняю асинхронную задачу из своего обработчика, она сразу же приводит к сбою приложения с NullPointerException.

Мой обработчик выглядит примерно так

  public Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
        handler.post(new Runnable() {
          @Override
          public void run() {
            new sortNearby().execute();
          }

        });
    }
  };

Вот часть трассировки стека из приложения, показывающая исключение

Caused by: java.lang.NullPointerException
at badams.android.app.fragments.MainMenu_NearbyFragment$sortNearby.doInBackground(MainMenu_NearbyFragment.java:100)

Строка 100 моего кода является первой строкой в ​​асинхронной задаче под doInBackground.

protected String doInBackground(String... args) {
  for (int i = 0; i < global.places.size(); i++) { //this is line 100

Я понимаю, что исключение, скорее всего, происходит из-за того, что "global.places.size()", вероятно, имеет значение null, но я застрял в том, почему он делает это только при вызове из обработчика, поскольку он отлично работает, если я запускаю задачу из любой другой раздел моего кода.

ИЗМЕНИТЬ

По просьбе @Raghunandan, вот весь блок кода из doInBackground в моей асинтаске, который вычисляет расстояние между «местом» и пользователем:

class sortNearby extends AsyncTask<String, Place, String> {
protected String doInBackground(String... args) {
  for (int i = 0; i < global.places.size(); i++) { //THIS IS LINE 100
    Location locationA = new Location("place");
    locationA.setLatitude(global.places.get(i).getLatitude());
    locationA.setLongitude(global.places.get(i).getLongitude());
    Location locationB = new Location("user");
    locationB.setLatitude(global.applicationLocationManager.getLatitude());
    locationB.setLongitude(global.applicationLocationManager.getLongitude());
    float dist = locationA.distanceTo(locationB);
    dist = dist / 1000;
    global.places.get(i).setDistance(dist);
  }
  return null;
}

ИЗМЕНИТЬ 2

global — это класс, расширяющий приложение, и он определяется в действии следующим образом:

global = (ApplicationGlobal) getActivity().getApplicationContext();

person Badams    schedule 18.04.2013    source источник
comment
@Raghunandan обновил вопрос, указав весь блок кода doInBackground.   -  person Badams    schedule 18.04.2013
comment
asycntask должен загружаться в поток пользовательского интерфейса. developer.android.com/reference/android/os/AsyncTask.html. Ознакомьтесь с правилами создания тем   -  person Raghunandan    schedule 18.04.2013
comment
@Raghunandan handler.post() работает в потоке пользовательского интерфейса, не так ли??   -  person Badams    schedule 18.04.2013
comment
Важнейшая часть не в том, doInBackground, а в том, откуда берется global.places?   -  person dmon    schedule 18.04.2013
comment
Рагунандан прав, см. этот другой вопрос . Почему вы пытаетесь запустить его из обработчика?   -  person dmon    schedule 18.04.2013
comment
Должен загружаться в поток пользовательского интерфейса public void handleMessage(Message msg) { runOnUiThread(new Runnable() {.....   -  person Raghunandan    schedule 18.04.2013
comment
@dmon Обработчик получает сообщение от отдельного класса GPS во время onLocationUpdate. Мне нужно, чтобы при вызове onLocationUpdate выполнялась асинхронная задача в моей деятельности.   -  person Badams    schedule 18.04.2013
comment
Почему бы не создать экземпляр асинхронной задачи в onLocationUpdate?   -  person dmon    schedule 18.04.2013
comment
@dmon Я обновляю представления в действии, используя publishProgress() в асинхронной задаче (извините, что этой части не было в примере кода в вопросе), поэтому асинхронная задача должна выполняться в этом действии. Есть ли способ выполнить асинтаск из другого класса?   -  person Badams    schedule 18.04.2013
comment
Итак, сделайте так, чтобы эта активность реализовывала LocationListener?   -  person dmon    schedule 18.04.2013
comment
мы не можем вызвать асинтаск из обработчика @Badams   -  person Venkat    schedule 18.04.2013
comment
@dmon, просто реализующий его, не вызывает вызова onLocationChanged. Я уверен, что это сработает, если я создам LocationManager и инициализирую GPS в действии, но причина, по которой я использую отдельный класс, заключается в том, что мне нужен GPS для нескольких действий/приложений. Вот почему у меня так много проблем. Может быть, я иду об этом неправильно?   -  person Badams    schedule 18.04.2013
comment
Если вы не разделяете большую часть обработки, может быть лучше сохранить GPS только тогда, когда вы действительно его используете.   -  person dmon    schedule 18.04.2013


Ответы (1)


Если NullPointerException находится в строке 100, то global или global.places возвращает null.

Вы пробовали отлаживать то же самое?

Отладка поможет вам следить за тем, что происходит.

Также из обработчика я не вижу, как вызывается ваш метод doInBackground?

Где определена переменная global? Где и когда он инициализируется?

person Bhushan Bhangale    schedule 18.04.2013
comment
нет необходимости вызывать doInBackground() как переопределенный метод, и он будет выполнен, как только выполнится onPreExecute() - person Raghunandan; 18.04.2013
comment
Да, я вижу это сейчас. Когда я ответил, класс, расширяющий AsyncTask, отсутствовал. Но где/как инициализируется глобальная переменная, по-прежнему отсутствует. - person Bhushan Bhangale; 18.04.2013
comment
@BhushanBhangale там под Edit 2 - person Badams; 18.04.2013
comment
@Badams да, я вижу это сейчас, когда вы отредактировали после того, как я ответил. В любом случае, не могли бы вы подтвердить вопрос о глобальных переменных и отладке? - person Bhushan Bhangale; 18.04.2013
comment
Глобальный объект @BhushanBhangale инициализируется во время действия onResume. Что касается отладки, я не слишком знаком с отладчиком, я уверен, что он мог бы избавить меня от этого вопроса, если бы у меня было немного больше опыта с ним. - person Badams; 18.04.2013
comment
@Badams Боюсь, без дополнительного подтверждения, устанавливается ли глобальная переменная или нет, и ссылается ли метод doInBackground на ту же глобальную переменную, это сложно. Отладка очень проста в eclipse или intellij, если вы ее используете, проверьте это для eclipse agile.csc.ncsu.edu/SEMaterials/tutorials/eclipse-debugger - person Bhushan Bhangale; 18.04.2013