Нулевая ссылка WebView

avatar
DonatasP
8 апреля 2018 в 10:47
631
3
2

У меня проблема с панелью push-уведомлений в моем приложении для Android... Когда пользователь пытается нажать кнопку на ней, мое приложение вылетает, выдавая ошибку ссылки на нулевой объект:

E/AndroidRuntime: НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: IntentService[NotificationActionService] Процесс: tk.ypod.ypod, PID: 24013 java.lang.NullPointerException: попытка вызвать виртуальный метод «android.view.View android.view.View.findViewById(int)» для нулевой ссылки на объект

Я безуспешно пытался исправить эту ошибку в течение нескольких часов, поэтому теперь я прошу вас о помощи.

Мой код:

package tk.ypod.ypod;

import android.app.IntentService;
import android.content.Intent;
import android.media.MediaPlayer;
import android.util.Log;
import android.webkit.WebChromeClient;
import android.webkit.WebView;

public class NotificationActionService extends IntentService {
static final String LOG_TAG = MainActivity.class.getSimpleName();
private MediaPlayer mp;
private WebView webview;

public NotificationActionService() {
    super( "NotificationActionService" );
}

@Override
protected void onHandleIntent(Intent intent) {
    webview = webview.findViewById(R.id.activity_notification_webview);
    webview.setWebChromeClient( new WebChromeClient() );
    webview.setWebViewClient(new WebClient() {
    });

    String action = intent.getAction();
    Log.e( LOG_TAG, "Received notification action: " + action );
    if ("Previous".equals( action )) {
        webview.loadUrl( "javascript: previous();" );
    } else if ("Next".equals( action )) {
        webview.loadUrl( "javascript: next();" );
    } else if ("Stop".equals( action )) {
        if (mp.isPlaying()) {
            webview.loadUrl( "javascript: stopVideo();" );
            mp.stop();
        }
    } else if ("Play".equals( action )) {
        if (mp.isPlaying()) {
            webview.loadUrl( "javascript: playVideo();" );
            mp.start();
        }
    }
}
}

Мой манифест

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="tk.ypod.ypod" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
    android:allowBackup="true"
    android:label="yPOD"
    android:hardwareAccelerated="true"
    android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >

    <activity
        android:name="tk.ypod.ypod.MainActivity"
        android:label="yPOD" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service android:name=".NotificationActionService" />
</application>

Редактировать, создание уведомления: Намерение

Intent intent = new Intent(MainActivity.this, MainActivity.class);
intent.putExtra("Next",true);
PendingIntent nextIntent = PendingIntent.getActivity(MainActivity.this, 1, intent, 0);

Регистрация onCreate()

boolean nextFlag = getIntent().getBooleanExtra("Next",false);
if(nextFlag) {
    webview.evaluateJavascript( "javascript:next()",
        new ValueCallback <String>() {
            @Override
            public void onReceiveValue(String value) {
                Log.e( LOG_TAG, "Next workded " + value );
            }
        }
    );
}
Источник

Ответы (3)

avatar
Sagar
8 апреля 2018 в 13:53
1

Я не знаю, чего вы пытаетесь достичь, но я уверен, что ваш подход нуждается в улучшении

Во-первых, нулевой указатель связан с тем, что вы не инициализировали WebView, но вызвали следующее: webview = webview.findViewById(R.id.activity_notification_webview)

Во-вторых, вы выполняете операции пользовательского интерфейса (используя в вашем случае WebView) из IntentService, что не будет работать, поскольку IntentService запускается в рабочем потоке.

Я бы рекомендовал вам переместить ваш код, обрабатывающий WebView, в Activity или Fragment.

DonatasP
8 апреля 2018 в 14:10
0

Это намерение используется для обработки кнопок уведомлений, без него я не знаю, как справиться с тем, какую кнопку нажал пользователь.

Sagar
8 апреля 2018 в 14:12
0

Вы можете следовать этому SO для этого

DonatasP
9 апреля 2018 в 10:19
0

Я пытался сделать что-то подобное, но снова безуспешно... Теперь пользователь может нажать кнопку, и это не приводит к сбою приложения, но мой webview.loadurl загружает домашнюю страницу вместо выполнения javascript и показывает ее в новом представлении.

DonatasP
9 апреля 2018 в 10:21
0

Я пытался сделать это: Intent intent = new Intent(MainActivity.this, MainActivity.class); intent.putExtra("Next",true); PendingIntent nextIntent = PendingIntent.getActivity(MainActivity.this, 1, intent, 0);, а затем в onCreate это: boolean nextFlag = getIntent().getBooleanExtra("Next",false); if(nextFlag){ webview.loadUrl("javascript:next()"); }

Sagar
9 апреля 2018 в 10:29
0

Вы намерены выполнить метод javascript на домашней странице? Где вы определяете next();?

DonatasP
9 апреля 2018 в 10:46
0

javascript: next() должен быть загружен на текущей странице пользователя, а не на домашней странице

Sagar
9 апреля 2018 в 11:10
0

Вы пробовали использовать webView.evaluateJavascript()? Вместо loadUrl ()

Sagar
9 апреля 2018 в 11:32
0

Можете ли вы обновить свой вопрос с кодом для действия и кодом создания намерения для уведомлений? Немного хлопотно читать комментарии.

Sagar
9 апреля 2018 в 12:58
0

В вашем случае вы перезапускаете ту же активность (MainActivity). В зависимости от флага, который вы отправили в манифесте, он может не вызывать onCreate. Для этого вам нужно использовать широковещательный приемник. Вы можете проверить это SO

DonatasP
9 апреля 2018 в 16:37
0

Мне нужно создать класс отдельно от java-файла моей активности для приемника, да? Если это так, я не мог бы вызвать веб-просмотр оттуда, не так ли?

avatar
pradithya aria
8 апреля 2018 в 14:06
0

E/AndroidRuntime: НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: IntentService[NotificationActionService] Процесс: tk.ypod.ypod, PID: 24013 java.lang.NullPointerException: попытка вызвать виртуальный метод 'android.view.View android.view.View.findViewById(int)' на нуле ссылка на объект

Ошибка связана с тем, что вы пытаетесь получить доступ к компоненту пользовательского интерфейса из Service, а это невозможно. Вы должны разместить приведенный выше код в Activity и взаимодействовать с ним с вашего Service, используя LocalBroadcastmanager или Messenger.

avatar
Anton Makov
8 апреля 2018 в 14:03
0

Когда вы используете службу, у вас нет доступа к представлениям (которые обычно используются в действиях или фрагментах), вам нужно использовать либо широковещательный получатель, либо ожидающее намерение для отправки данных из вашей службы в активность, ваша активность будет считывать данные и соответственно загружать/изменять представления.