0

I feel like the answer should be obvious but I can't find it. How do I reference a WebView in my main activity from Application class? Using a public static var to hold a reference to it in Activity class is causing a memory leak.

Current code (works, but causes memory leak).

Activity

public class Core extends AppCompatActivity {

public static WebView coreView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_core);

    WebView myWebView = (WebView) findViewById(R.id.webview);
    WebSettings webSettings = myWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setDomStorageEnabled(true);
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
    myWebView.setWebViewClient(new WebViewClient());
    myWebView.setPadding(0,80,0,0);

    coreView = myWebView;
}
}

Application

public class App extends Application {
@Override
public void onCreate() {
    super.onCreate();

    Core.coreView.loadUrl("http://www.google.com");

}

EDIT: Full App class.

public class App extends Application {
@Override
public void onCreate() {
    super.onCreate();

    OneSignal.startInit(this)
            .inFocusDisplaying(OneSignal.OSInFocusDisplayOption.Notification)
            .setNotificationOpenedHandler(new MainNotificationOpenedHandler())
            .setNotificationReceivedHandler(new MainNotificationReceivedHandler())
            .unsubscribeWhenNotificationsAreDisabled(true)
            .init();

    OSPermissionSubscriptionState status = OneSignal.getPermissionSubscriptionState();
}

private class MainNotificationOpenedHandler implements OneSignal.NotificationOpenedHandler {
    // This fires when a notification is opened by tapping on it.
    @Override
    public void notificationOpened(OSNotificationOpenResult result) {
        OSNotificationAction.ActionType actionType = result.action.type;
        JSONObject data = result.notification.payload.additionalData;
        String customKey;

        Core.coreView.loadUrl(result.notification.payload.launchURL);
    }
}

private class MainNotificationReceivedHandler implements OneSignal.NotificationReceivedHandler {
    @Override
    public void notificationReceived(OSNotification notification) {
        JSONObject data = notification.payload.additionalData;
    }

}

}

dakishimesan
  • 118
  • 4

1 Answers1

1

How do I reference a WebView in my main activity from Application class?

You don't. You move that code into the activity, or something scoped to that activity (e.g., a fragment).

For example, your code in your question is guaranteed to crash, as Core.coreView will not be set by the time onCreate() of an Application is called. onCreate() of an Application is called before any components, such as an activity, are created, as part of your process starting.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • You are absolutely right about crash on run, I simplified the code for the question but Core.coreView.loadUrl("http://www.google.com"); was actually in an event handler, not in the Application constructor. Regardless I take your point. So Application code should never be used to modify Activity? What I am trying to do is use the OneSignal SDK to change the webview url when the user receives a notification. OneSignal indicates that initialization/handlers for notification should be in the extends Application class. So if the handler is in Application, how to tell webview to change url? – dakishimesan Aug 01 '17 at 23:06
  • PS: Full App class added to original post. Thank you for your help! – dakishimesan Aug 01 '17 at 23:13
  • @dakishimesan: Use an event bus (greenrobot's EventBus, `LocalBroadcastManager`, something Rx-based, etc.). Have your `MainNotificationOpenedHandler` post an event on the bus. Have your activity register for events on the bus and respond as appropriate. Done properly, this eliminates the memory leak and also handles cases where the activity was destroyed (e.g., user navigation). – CommonsWare Aug 01 '17 at 23:27
  • Okay that makes a lot more sense to me now, THANK YOU very much. – dakishimesan Aug 01 '17 at 23:38
  • This was truly helpful, thank you. FYI for those reading this later I implemented LocalBroadcastManager sender/receiver and this post was useful: https://stackoverflow.com/questions/8802157/how-to-use-localbroadcastmanager – dakishimesan Aug 02 '17 at 01:04