I have a few things that need to be done asynchronously during my application’s startup process. I’ve created an abstract class that derives from AsyncTask which implements things common to these loading tasks:
protected abstract class LoadTask extends AsyncTask<Object, Void, Object>{
MainActivity activity;
void detach(){
activity = null;
}
void attach(MainActivity a){
activity = a;
}
public LoadTask(MainActivity a){
super();
attach(a);
}
public abstract boolean shouldRun();
@Override
protected void onPostExecute(Object result){
activity.onFinishLoad(this.getClass(), result);
}
}
Following is one particular implementation of a concrete subclass:
public class ItemInfoLoadTask extends LoadTask{
public ItemInfoLoadTask(MainActivity a){
super(a);
}
public boolean shouldRun(){
return should_reload("items", item_info_path);
}
@Override
protected Object doInBackground(Object ... params) {
setProgressMessage("Reading item info...");
JSONObject result = loadItemInfo();
return result;
}
private JSONObject loadItemInfo(){
return Util.parseJSONObject(item_info_path);
}
}
And here is the code that calls these from within the onCreate() method of my activity:
Log.v(TAG, c.getName());
Class[] types = {MainActivity.class};
Constructor construct = c.getConstructor(types);
task = (LoadTask)(construct.newInstance(this));
And here is the log:
12-17 10:26:25.750: V/MainActivity(25188): com.mycompany.mypackage.MainActivity$ItemInfoLoadTask
12-17 10:26:25.760: E/MainActivity(25188): this shouldn't happen
12-17 10:26:25.760: E/MainActivity(25188): java.lang.NoSuchMethodException: <init> [class com.mycompany.mypackage.MainActivity]
12-17 10:26:25.760: E/MainActivity(25188): at java.lang.ClassMembers.getConstructorOrMethod(ClassMembers.java:235)
12-17 10:26:25.760: E/MainActivity(25188): at java.lang.Class.getConstructor(Class.java:459)
12-17 10:26:25.760: E/MainActivity(25188): at com.mycompany.mypackage.MainActivity.onCreate(MainActivity.java:80)
12-17 10:26:25.760: E/MainActivity(25188): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
12-17 10:26:25.760: E/MainActivity(25188): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1715)
12-17 10:26:25.760: E/MainActivity(25188): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1767)
12-17 10:26:25.760: E/MainActivity(25188): at android.app.ActivityThread.access$1500(ActivityThread.java:122)
12-17 10:26:25.760: E/MainActivity(25188): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1005)
12-17 10:26:25.760: E/MainActivity(25188): at android.os.Handler.dispatchMessage(Handler.java:99)
12-17 10:26:25.760: E/MainActivity(25188): at android.os.Looper.loop(Looper.java:132)
12-17 10:26:25.760: E/MainActivity(25188): at android.app.ActivityThread.main(ActivityThread.java:4028)
12-17 10:26:25.760: E/MainActivity(25188): at java.lang.reflect.Method.invokeNative(Native Method)
12-17 10:26:25.760: E/MainActivity(25188): at java.lang.reflect.Method.invoke(Method.java:491)
12-17 10:26:25.760: E/MainActivity(25188): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
12-17 10:26:25.760: E/MainActivity(25188): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
12-17 10:26:25.760: E/MainActivity(25188): at dalvik.system.NativeStart.main(Native Method)
I can’t figure out what I’m doing wrong. If it matters any(although I can’t see why it should), LoadTask and ItemInfoLoadTask are inner classes in MainActivity
Non-static inner classes contain implicit reference to the instance of the enclosing class. All constructors of such inner classes take reference to the instance of enclosing class as an argument.
A simple example:
prints
public Foo$Bar(Foo,int)– note the firstFooparameter.The javap tool can show information about structure – declared fields, methods and constructors of
Foo$Bar.class:Here you can see this implicit reference to the parent. JVM doesn’t know about inner classes so the compiler has to introduce synthetic methods and fields to achieve required behavior. It is usually remain unnoticed until you need something like reflection.
In your particular case you can either make your inner classes static so there will be no implicit reference or remove explicit reference to the
MainActivity.