Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.imqa.asm.FragmentMakerFinder Maven / Gradle / Ivy
package io.imqa.asm;
import org.objectweb.asm.*;
import io.imqa.injector.MappingDecoder;
import io.imqa.injector.util.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
public class FragmentMakerFinder implements Finder {
HashMap lifeCycle = new HashMap<>(); // onCreateView, onStart, onResume
public void init() {
lifeCycle.clear();
lifeCycle.put("onCreate", false);
lifeCycle.put("onCreateView", false);
lifeCycle.put("onStart", false);
lifeCycle.put("onResume", false);
}
public boolean find(String name, String superName, String[] interfaces) {
if (checkFragmentClass(superName)) {
if (!checkAndroidClass(name)) {
Logger.d("SuperClass name", superName);
return true;
}
}
return false;
}
private boolean checkFragmentClass(String name) {
if (name.equals(MappingDecoder.getInstance().findClass("android/support/v4/app/Fragment"))
|| name.equals(MappingDecoder.getInstance().findClass("android/support/v4/app/DialogFragment"))
|| name.equals(MappingDecoder.getInstance().findClass("android/support/v4/app/ListFragment"))
|| name.equals(MappingDecoder.getInstance().findClass("android/support/v4/app/PreferenceFragment"))
|| name.equals(MappingDecoder.getInstance().findClass("androidx/fragment/app/Fragment"))
|| name.equals(MappingDecoder.getInstance().findClass("android/app/Fragment"))) {
Logger.d("Fragment class", name);
return true;
}
return false;
}
private boolean checkAndroidClass(String name) {
String[] steps = name.split("/");
if (steps[0].equals("android")) return true;
String packageName = name.substring(0, name.lastIndexOf("/"));
if (packageName.equals(MappingDecoder.getInstance().findClass("android/support/v7/app"))
|| packageName.equals(MappingDecoder.getInstance().findClass("android/support/v4/app"))
|| packageName.equals(MappingDecoder.getInstance().findClass("androidx/fragment/app"))) {
return true;
}
return false;
}
private boolean checkMethod(String name, String[] allowedNameList) {
for(String allowedName : allowedNameList) {
if (name.equals(allowedName))
return true;
}
return false;
}
private String[] getFragmentMethod() {
List methodList = new ArrayList();
//methodList.add("onAttach");
methodList.add("onCreate");
methodList.add("onCreateView");
methodList.add("onActivityCreated");
methodList.add("onViewStateRestored");
methodList.add("onStart");
methodList.add("onResume");
/*
methodList.add("onPause");
methodList.add("onStop");
methodList.add("onDestroyView");
methodList.add("onDestroy");
methodList.add("onDetach");
*/
String[] methodArray = new String[methodList.size()];
methodList.toArray(methodArray);
return methodArray;
}
public MethodVisitor getVisitor(String[] interfaceList, String className, String superName,
int access, String name, String desc, MethodVisitor mv) {
if (find(className, superName, interfaceList)
&& checkMethod(name, getFragmentMethod())) {
Logger.d("Fragment Inject", className + ", Method : "+name);
setVisited(name);
return new FragmentVisitor(className, access, name, desc, mv);
}
for (String interfaceName : interfaceList) {
if (find(className, interfaceName, interfaceList)
&& checkMethod(name, getFragmentMethod())) {
Logger.d("Fragment Inject", className + ", Method : "+name);
setVisited(name);
return new FragmentVisitor(className, access, name, desc, mv);
}
}
return mv;
}
@Override
public void visitEnd(ClassVisitor cv, String className, String superClass, String[] interfaceList) {
boolean visited = false;
if (find(className, superClass, interfaceList)) {
makeVisit(cv, className, superClass);
visited = true;
}
for (String interfaceName : interfaceList) {
if (find(className, interfaceName, interfaceList) && !visited) {
makeVisit(cv, className, superClass);
visited = true;
}
}
cv.visitEnd();
}
protected void setVisited(String name) {
switch (name) {
case "onCreate":
case "onCreateView":
case "onStart":
case "onResume":
lifeCycle.replace(name, true);
break;
}
}
protected void makeVisit(ClassVisitor cv, String className, String superClass) {
// 프래그먼트 클래스에 Life cycle 구현 안된 곳이 있다면 새로 작성
Set cycleNames = lifeCycle.keySet();
for(String cycleName : cycleNames) {
if (!lifeCycle.get(cycleName)) {
String desc = "()V";
switch (cycleName) {
case "onCreate":
desc = MappingDecoder.getInstance().decodeDesc("(Landroid/os/Bundle;)V");
break;
case "onCreateView":
desc = MappingDecoder.getInstance().decodeDesc("(Landroid/view/LayoutInflater;Landroid/view/ViewGroup;Landroid/os/Bundle;)Landroid/view/View;");
break;
}
FragmentMakerVisitor lifecyclemv;
MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, cycleName, desc, null, null);
lifecyclemv = new FragmentMakerVisitor(
className,
Opcodes.ACC_PUBLIC,
cycleName,
superClass,
desc,
mv);
lifecyclemv.visitCode();
// Call onMethodExit()
if (cycleName.equals("onCreateView")) {
lifecyclemv.visitInsn(Opcodes.ARETURN);
} else {
lifecyclemv.visitInsn(Opcodes.RETURN);
}
lifecyclemv.endMethod();
}
}
}
}