FIrst off I am working on an application that needs to run JavaScript when the app is not in the foreground; the problem appears to be that when the app is put into the background/ the webview is detached from the screen the webview's onPause method is called which per docs does the following: "Pauses any extra processing associated with this WebView and its associated DOM, plugins, JavaScript etc."
From what I've found thus far my best bet seems to be using reflection to call the webview's "onResume" method which should undo all these process suspensions. With my current implementation I get an instance of said method but when invoked nothing appears to happen as my subsequent JavaScript call does nothing (mind you this works when I have the application open and in the foreground).
Anyone else see an issue im my code or have a solution to running JavaScript when your app is in the background without fully launching the app?
Push message comes in saying JavaScript needs to be ran so intent is sent to notify service running in background:
Intent intent = new Intent( "some action" );
intent.putExtra( "xtifyJson", xtifyJSON.toString() );
context.sendBroadcast( intent );
In the onReceive of my Broadcast receiver, which lives in the background service always running:
final String stringArrayExtra = intent.getStringExtra( "xtifyJson" );
if ( !Text.isNull( stringArrayExtra ) ) {
new Handler( context.getMainLooper() ).post( new Runnable() {
@Override
public void run() {
try {
Log.d( "Hey Dev Guy", "Message received" );
JavaScriptInterface javaScriptInterface = ( (SpecialApplication) getApplicationContext() ).getJavaScriptInterface();
relectHiddenMethod( javaScriptInterface.getParentWebView(), "onResume" );
javaScriptInterface.getParentWebView().resumeTimers();
javaScriptInterface.callBackPushReceived( new JSONObject( stringArrayExtra ) );
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} );
}
reflectHiddenMethod reflection method:
private void reflectHiddenMethod( final WebView webview, final String name ) {
if ( webview != null ) {
try {
Method method = WebView.class.getMethod( name );
Object invoke = method.invoke( webview );
}
catch (final Exception e) {
e.printStackTrace();
}
}
}
Unfortunately this won't work. A WebView is a UI component and thus needs to be attached to the window. There are other references here on StackOverflow about this like here: Android webview inside a service?.
One possibility would be to look into alternative JavaScript libraries to execute your code without the need for a WebView, e.g. Rhino, V8, or spidermonkey.
But probably the best solution would be to implement your push messaging in Java instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With