Исключение нулевого указателя в onPostExecute

Я понятия не имею, как определить, где возникает это исключение нулевого указателя.

Сбой произошел только один раз (пока) на физическом устройстве пользователя, как рекомендовано Google Play - мне не удалось воспроизвести его в среде отладки.

Stack Trace, который дает мне Google Play, кажется немного расплывчатым (несмотря на то, что я загрузил файл сопоставления для выпуска):

java.lang.NullPointerException: 
  at com.nooriginalthought.amalfi.getShortURL.a (getShortURL.java:11)
  at com.nooriginalthought.amalfi.getShortURL.onPostExecute (getShortURL.java:2)
  at android.os.AsyncTask.finish (AsyncTask.java:695)
  at android.os.AsyncTask.access$600 (AsyncTask.java:180)
  at android.os.AsyncTask$InternalHandler.handleMessage (AsyncTask.java:712)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:193)
  at android.app.ActivityThread.main (ActivityThread.java:6806)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:547)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:873)

Все, что я вижу, это то, что исключение создается функцией onPostExecute в моем классе getShortURL (это асинхронная задача, которая вызывает битовый API).

Код работает нормально, и сообщалось только об одном сбое.

Код в onPostExecute очень прост (включая номера строк исходного кода):

1320    @Override
1321    protected void onPostExecute(String shortURL) {
1322        super.onPostExecute(shortURL);
1323        mainActivityWeakReference.get().shortURLreturn(shortURL);
1324    }

(shortURLreturn определен в моем классе MainActivity)

Как я могу понять, что на самом деле вызвало эту ошибку?

Это сложный вопрос. '.A' - верный признак того, что getShortURL был запутан, но, очевидно, только частично (поскольку onPostExecute указан в списке) - возможно, вы используете неправильную карту для деобфускации? Разве WeakReference.get не может возвращать null всякий раз, когда решает сборщик мусора?

Andy 12.11.2018 19:04
@NonNull String shortURL
Martin Zeitler 12.11.2018 19:57
2
2
254
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кода опубликовано не так много, так что в основном будут гадания.

Насколько вы уверены, что mainActivityWeakReference не является нулевым, поскольку это слабая ссылка? Проверьте эту ссылку, чтобы узнать, как использовать слабые эталонные действия ссылка. Что-то вроде:

@Override
protected void onPostExecute(String shortURL) {
  MainActivity mainActivity = mainActivityWeakReference.get();
  if (mainActivity != null) {
     mainActivity.shortURLreturn(shortURL);
  }
}

Кроме того, для такого рода действий вам на самом деле не нужна слабая ссылка на действие (конечно, только если вам не нужны какие-либо методы, которые действительно принадлежат классу Android Activity). Если вам нужны только ваши общедоступные методы, которые вы реализовали в MainActivity, вы можете создать интерфейс, например:

interface ShortUrlReceiveCallback {
   void onReceive(String shortURL);
}

и тогда вы просто сохраните эту ссылку в конструкторе класса getShortURL (обратите внимание, что классы начинаются с верхнего регистра), а затем вызовите в onPostExecute -> shortUrlReceiveCallback.onReceive (shortURL); и пусть ваш MainActivity реализует этот ShortActivityCallback.

Что касается моей второй точки, помните, что onPostExecute происходит в другом потоке (поток ввода-вывода / фоновый поток), чем MainActivity (UiThread), если вы делаете что-либо после этого, что должно быть в основном потоке или потокобезопасном (настройка переменных должна быть потокобезопасной ; попробуйте использовать блокировки, если вы этого не сделаете, например:

class MainActivity {
   private String mainShortUrl;
   private Lock urlReturnLock = new ReentrantLock();
   ...
   public void shortURLReturn(String shortUrl) {
      urlReturnLock.lock();
      try {
         mainShortUrl = shortUrl;
      } finally {
         urlReturnLock.unlock();
      }
   }
}

Итак, если я правильно понимаю, я смогу избежать нулевого указателя, просто проверив, что моя недельная ссылка все еще существует (не является нулем), прежде чем выполнять что-либо полезное в onPostExecute? И единственная причина, по которой недельная ссылка будет нулевой, заключается в том, что сборщик мусора уничтожил ее, и у пользователя был похожий процесс - и в этом случае моей асинхронной задаче все равно не к чему было бы возвращаться, поэтому моя функция возврата не выполняется. было бы хорошо. Я правильно понял? (А еще про interface интересно в другой раз, спасибо!)

Fat Monk 12.11.2018 22:54

Другие вопросы по теме