package org.bbs.apklauncher;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
public class ViewCreater {
private static final String TAG = ViewCreater.class.getSimpleName();
// phonelayoutinfaltor
private static final String[] sClassPrefixList = {
"android.view.",
"android.widget.",
"android.webkit.",
"android.app." };
public static View onCreateView(String name, Context context,
AttributeSet attrs, ClassLoader hostClassLoader, ClassLoader targetClassLoader, final Object activity
// .final Class clazz
) {
View v = null;
if (name.contains(".")) {
v = createView(name, context, attrs, targetClassLoader);
} else {
for (String prefix : sClassPrefixList) {
v = createView(prefix + name, context, attrs, hostClassLoader);
if (null != v) {
break;
}
}
}
if (null != v) {
int attributeCount = attrs.getAttributeCount();
for (int i = 0; i < attributeCount; i++) {
String attName = attrs.getAttributeName(i);
// Log.d(TAG, "attName: " + attName);
if ("onClick".equals(attName)) {
final String handlerName = attrs.getAttributeValue(i);
if (!TextUtils.isEmpty(handlerName)) {
Log.d(TAG, "re-adjust onClick listener. handlerName: " + handlerName);
v.setOnClickListener(new OnClickListener() {
private Method mHandler;
@Override
public void onClick(View v) {
if (mHandler == null) {
try {
mHandler = activity
.getClass()
.getMethod(handlerName,
View.class);
} catch (NoSuchMethodException e) {
int id = v.getId();
String idText = id == View.NO_ID ? ""
: " with id '"
+ v.getContext()
.getResources()
.getResourceEntryName(
id)
+ "'";
throw new IllegalStateException(
"Could not find a method "
+ handlerName
+ "(View) in the activity "
+ activity
+ " for onClick handler"
+ " on view "
+ v.getClass() + idText,
e);
}
}
try {
mHandler.invoke(activity, v);
} catch (IllegalAccessException e) {
throw new IllegalStateException(
"Could not execute non "
+ "public method of the activity",
e);
} catch (InvocationTargetException e) {
throw new IllegalStateException(
"Could not execute "
+ "method of the activity",
e);
}
}
});
}
}
}
}
// Log.d(TAG, "onCreateView(). name: " + name + " v: " + v);
return v;
}
public static View createView(String className, Context context,
AttributeSet attrs, ClassLoader classLoader) {
try {
Class clazz = classLoader.loadClass(className);
Constructor construtor = clazz.getConstructor(new Class[] {
Context.class, AttributeSet.class });
return (View) construtor
.newInstance(new Object[] { context, attrs });
} catch (Exception e) {
if (!isAndroidFrameworkClass(className)) {
// FIXME to fix this error
Log.e(TAG, "can NOT createView. view: " + className + " classLoader: " + classLoader);
}
}
return null;
}
public static boolean isAndroidFrameworkClass(String className){
boolean is = false;
for (String prefix : sClassPrefixList) {
if (className.startsWith(prefix)){
is = true;
break;
}
}
return is;
}
}