Reputation: 24181
im developping an app and inside it i'm using cordova
Api to communicate between Sencha
code and *Android native Code*
.
inside my plugin's execute
method , i'm launching an AsyncTask
( for device registration) , but i got ExceptionInInitializerError
in line 36 ( instanciation of TaskDeviceRegistration
).
RegistrationDevicePlugin :
public class DeviceRegistrationPlugin extends Plugin {
public static final String TAG = "DeviceRegistrationPlugin";
public static final String ACTION_REGISTER_DEVICE = "registerDeviceAction";
protected String callBackMethod;
@Override
public PluginResult execute(String action, JSONArray args, String callBackId) {
String token;
if(action.equals(ACTION_REGISTER_DEVICE)) {
try {
token = args.getString(0);
if(token != null) {
// launch the task to register device
SharedPreferences prefs = cordova.getActivity().getSharedPreferences(WebServiceRequest.PREFS_IDENTIFICATION, Context.MODE_PRIVATE);
prefs.edit().putString(WebServiceRequest.PREF_TOKEN_PARAM, token).commit();
TaskRegisterDevice task = new TaskRegisterDevice(cordova.getActivity());// this is the line 36
task.execute();
// tell the plugin that the callBack will be executed after the task
// has finished his work.
this.callBackMethod = callBackId;
PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT);
pluginResult.setKeepCallback(true);
return pluginResult;
}
else {
return new PluginResult(Status.ERROR, "token required");
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
}
else {
// invalid action sended to the plugin
return new PluginResult(PluginResult.Status.INVALID_ACTION);
}
}
/**
* asynctask to register the device
* @author houcine
*
*/
class TaskRegisterDevice extends AsyncTask<Void, Void, Boolean> {
protected Context context;
public TaskRegisterDevice(Context context) {
this.context = context;
}
@Override
protected Boolean doInBackground(Void... params) {
try {
return WebServiceRequest.RegisterDevice(context);
} catch (JSONException e) {
e.printStackTrace();
return true;
} catch (IOException e) {
e.printStackTrace();
return true;
}
}
@Override
protected void onPostExecute(Boolean result) {
// return new plugin result when synchronization done
Log.d(TAG, "resultat DeviceRegistration : "+result + " , \ncallBackMethod : "+callBackMethod);
PluginResult pluginResult = new PluginResult(
PluginResult.Status.OK, result);
pluginResult.setKeepCallback(false);
success(pluginResult, callBackMethod);
}
}
}
ManifestFile :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp.activity"
android:versionCode="1"
android:versionName="1.0.2" >
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:resizeable="true"
android:anyDensity="true"
/>
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="16"/>
//other stuff : declaration of <application> tag , activities , services...etc
>
and logCat :
01-01 06:54:26.251: E/AndroidRuntime(6189): FATAL EXCEPTION: Thread-31
01-01 06:54:26.251: E/AndroidRuntime(6189): java.lang.ExceptionInInitializerError
01-01 06:54:26.251: E/AndroidRuntime(6189): at com.myapp.plugins.DeviceRegistrationPlugin.execute(DeviceRegistrationPlugin.java:36)
01-01 06:54:26.251: E/AndroidRuntime(6189): at org.apache.cordova.api.PluginManager$1.run(PluginManager.java:192)
01-01 06:54:26.251: E/AndroidRuntime(6189): at java.lang.Thread.run(Thread.java:1096)
01-01 06:54:26.251: E/AndroidRuntime(6189): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
01-01 06:54:26.251: E/AndroidRuntime(6189): at android.os.Handler.<init>(Handler.java:121)
01-01 06:54:26.251: E/AndroidRuntime(6189): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
01-01 06:54:26.251: E/AndroidRuntime(6189): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
01-01 06:54:26.251: E/AndroidRuntime(6189): at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
01-01 06:54:26.251: E/AndroidRuntime(6189): ... 3 more
NOTE : the app is working just fine on HTC ONE S , HTC ONE X , SAMSUNG GALAXY S II , SAMSUNG GALAXY SIII with android sdk version : 4.0 or higher , but it doesn't work for devices with android version like : 2.2.2 , 2.3.5 , 2.3.3
Upvotes: 2
Views: 2446
Reputation: 30864
AsyncTask
should be created and executed on the UI thread. It looks like DeviceRegistrationPlugin.execute()
method is invoked outside the main thread that's why you are getting the error.
You can try to fix it this way:
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
TaskRegisterDevice task = new TaskRegisterDevice(cordova.getActivity());
task.execute();
}
});
Upvotes: 6