Я понятия не имею, как определить, где возникает это исключение нулевого указателя.
Сбой произошел только один раз (пока) на физическом устройстве пользователя, как рекомендовано 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)
Как я могу понять, что на самом деле вызвало эту ошибку?
@NonNull String shortURLКода опубликовано не так много, так что в основном будут гадания.
Насколько вы уверены, что 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 интересно в другой раз, спасибо!)
Это сложный вопрос. '.A' - верный признак того, что getShortURL был запутан, но, очевидно, только частично (поскольку onPostExecute указан в списке) - возможно, вы используете неправильную карту для деобфускации? Разве WeakReference.get не может возвращать null всякий раз, когда решает сборщик мусора?