Skip to content

Commit b61fe41

Browse files
authored
Merge pull request #95 from Meituan-Dianping/optimize
修复自动化补丁在方法参数是数组的bug
2 parents 5695f1a + a4f7e88 commit b61fe41

12 files changed

Lines changed: 75 additions & 56 deletions

File tree

README-zh.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
apply plugin: 'robust'
2727
2828
29-
compile 'com.meituan.robust:robust:0.3.3'
29+
compile 'com.meituan.robust:robust:0.3.4'
3030
3131
```
3232
2. 在整个项目的build.gradle加入classpath
@@ -37,8 +37,8 @@
3737
jcenter()
3838
}
3939
dependencies {
40-
classpath 'com.meituan.robust:gradle-plugin:0.3.3'
41-
classpath 'com.meituan.robust:auto-patch-plugin:0.3.3'
40+
classpath 'com.meituan.robust:gradle-plugin:0.3.4'
41+
classpath 'com.meituan.robust:auto-patch-plugin:0.3.4'
4242
}
4343
}
4444
```

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Robust is an Android HotFix solution with high compatibility and high stability.
2424
//please uncomment fellow line before you build a patch
2525
//apply plugin: 'auto-patch-plugin'
2626
apply plugin: 'robust'
27-
compile 'com.meituan.robust:robust:0.3.3'
27+
compile 'com.meituan.robust:robust:0.3.4'
2828
```
2929
2. Add below codes in the outest project's build.gradle file.
3030

@@ -34,8 +34,8 @@ Robust is an Android HotFix solution with high compatibility and high stability.
3434
jcenter()
3535
}
3636
dependencies {
37-
classpath 'com.meituan.robust:gradle-plugin:0.3.3'
38-
classpath 'com.meituan.robust:auto-patch-plugin:0.3.3'
37+
classpath 'com.meituan.robust:gradle-plugin:0.3.4'
38+
classpath 'com.meituan.robust:auto-patch-plugin:0.3.4'
3939
}
4040
}
4141
```

app/robust/app-release.apk

210 Bytes
Binary file not shown.

app/robust/patch.jar

1.11 KB
Binary file not shown.

app/src/main/java/com/meituan/sample/SecondActivity.java

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import android.util.AttributeSet;
88
import android.util.Log;
99
import android.view.View;
10+
import android.widget.ArrayAdapter;
11+
import android.widget.BaseAdapter;
12+
import android.widget.ListView;
1013
import android.widget.TextView;
1114
import android.widget.Toast;
1215

@@ -23,20 +26,18 @@
2326

2427
import java.lang.ref.WeakReference;
2528
import java.lang.reflect.Field;
29+
import java.util.Arrays;
2630
import java.util.List;
2731

2832
public class SecondActivity extends AppCompatActivity implements View.OnClickListener {
2933

3034
protected String flag = "flagstring";
3135
protected static String name = "zhang";
32-
public int times = 0;
33-
public static String staticStringField = "meituan";
34-
public static int staticIntField = 12311111;
35-
public long longField = 123l;
3636
public Hll hll = new Hll(true);
3737
private People people = new People();
3838
public static State state = new State(new Hll(true));
39-
39+
private ListView listView;
40+
private String[] multiArr = {"列表1", "列表2", "列表3", "列表4"};
4041
private String inlineToString(){
4142
return super.toString();
4243
}
@@ -46,6 +47,8 @@ protected void onCreate(Bundle savedInstanceState) {
4647
super.onCreate(savedInstanceState);
4748
System.out.println(inlineToString());
4849
setContentView(R.layout.activity_main2);
50+
51+
listView = (ListView) findViewById(R.id.listview);
4952
//test lambda expression
5053
TextView textView = (TextView) findViewById(R.id.secondtext);
5154
textView.setOnClickListener(v -> {
@@ -80,6 +83,9 @@ protected void onCreate(Bundle savedInstanceState) {
8083
Bundle bundle=new Bundle();
8184
bundle.putInt("asd",1);
8285
bundle.getFloat("asd");
86+
//test array
87+
BaseAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, multiArr);
88+
listView.setAdapter(adapter);
8389
}
8490
/**
8591
* if you change the return value you will change the show text,in the demo we built a patch to change the text
@@ -91,11 +97,20 @@ public String getTextInfo(String meituan) {
9197
p.setCates(" AutoPatch");
9298
people.setName(" I am Patch");
9399
ConcreateClass concreateClass = new ConcreateClass();
94-
95-
// return "you make it!! name is " + p.getName() + " \npatch success " + people.getName() ;
100+
getArray(meituan);
101+
//打开这部分注释,查看修复效果
102+
// Arrays.fill(multiArr,"修复后的数据");
103+
// return "修复后:you make it!! name is " + p.getName() + " \npatch success " + people.getName() ;
96104
return "error occur " + concreateClass.getA();
97105
}
98106

107+
@Add
108+
public String[] getArray(String meituan) {
109+
People p = new People();
110+
p.setName("mivazhang");
111+
return new String[]{p.getName(),"meituan"};
112+
}
113+
99114
// another usage of Modify anntation
100115
// @Modify(value = "com.meituan.sample.SecondActivity.onCreate(android.os.Bundle)")
101116
private String getInfo(State stae, Super s, long l) {
@@ -140,18 +155,6 @@ public static String[] methodWithArrayParameters(String[] flag) {
140155
return flag;
141156
}
142157

143-
public Boolean getBoolean(String flag) {
144-
return false;
145-
}
146-
147-
public String getString(Hll hll) {
148-
return "meituan";
149-
}
150-
151-
public Super getStatus() {
152-
return new Super();
153-
}
154-
155158
@Override
156159
public void onClick(View v) {
157160
Toast.makeText(SecondActivity.this, "from implements onclick ", Toast.LENGTH_SHORT).show();

app/src/main/res/layout/activity_main2.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,10 @@
3131
android:layout_margin="@dimen/fab_margin"
3232
android:src="@android:drawable/ic_dialog_email" />
3333

34+
<ListView
35+
android:layout_width="318dp"
36+
android:layout_height="381dp"
37+
android:id="@+id/listview"
38+
android:layout_gravity="bottom|left"/>
39+
3440
</android.support.design.widget.CoordinatorLayout>

auto-patch-plugin/src/main/groovy/com/meituan/robust/autopatch/ReflectUtils.groovy

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ class ReflectUtils {
162162
}
163163
StringBuilder signureBuilder = new StringBuilder();
164164
String name;
165+
boolean isArray=false;
165166
for (int index = 1; index < signature.indexOf(")"); index++) {
166167
if (Constants.OBJECT_TYPE == signature.charAt(index) && signature.indexOf(Constants.PACKNAME_END) != -1) {
167168
name = signature.substring(index + 1, signature.indexOf(Constants.PACKNAME_END, index)).replaceAll("/", ".")
@@ -171,6 +172,10 @@ class ReflectUtils {
171172
signureBuilder.append(name);
172173
}
173174
index = signature.indexOf(";", index);
175+
if(isArray){
176+
signureBuilder.append("[]");
177+
isArray=false;
178+
}
174179
signureBuilder.append(".class,");
175180
}
176181
if (Constants.PRIMITIVE_TYPE.contains(String.valueOf(signature.charAt(index)))) {
@@ -185,8 +190,16 @@ class ReflectUtils {
185190
case 'D': signureBuilder.append("double"); break;
186191
default: break;
187192
}
193+
if(isArray){
194+
signureBuilder.append("[]");
195+
isArray=false;
196+
}
188197
signureBuilder.append(".class,");
189198
}
199+
200+
if (Constants.ARRAY_TYPE.equals(String.valueOf(signature.charAt(index)))) {
201+
isArray=true;
202+
}
190203
}
191204
if (signureBuilder.toString().length() > 0 && String.valueOf(signureBuilder.charAt(signureBuilder.toString().length() - 1)).equals(","))
192205
signureBuilder.deleteCharAt(signureBuilder.toString().length() - 1);
@@ -200,7 +213,6 @@ class ReflectUtils {
200213
if (e.signature == null) {
201214
return "{\$_=(\$r)\$proceed(\$\$);}";
202215
}
203-
204216
String signatureBuilder = getParameterClassSignure(e.signature, patchClassName);
205217
stringBuilder.append("{");
206218
if (isStatic) {
@@ -252,25 +264,6 @@ class ReflectUtils {
252264
}
253265

254266

255-
static int calculateParameterCount(String signature) {
256-
int endIndex = signature.indexOf(")") == -1 ? signature.length() : signature.indexOf(")")
257-
signature = signature.substring(0, endIndex)
258-
int parameterCount = 0;
259-
if (null == signature) {
260-
return 0;
261-
}
262-
for (int i = 0; i < signature.length(); i++) {
263-
//object parameter
264-
if (Constants.OBJECT_TYPE == (signature.charAt(i))) {
265-
i = signature.indexOf(";", i);
266-
parameterCount++;
267-
}
268-
if (Constants.PRIMITIVE_TYPE.contains(String.valueOf(signature.charAt(i)))) {
269-
parameterCount++;
270-
}
271-
}
272-
return parameterCount;
273-
}
274267

275268
private static String getParameterClassString(CtClass[] parameters) {
276269
if (parameters == null || parameters.length < 1) {
@@ -454,7 +447,7 @@ class ReflectUtils {
454447
if (!m.method.returnType.equals(CtClass.voidType)) {
455448
stringBuilder.append("\$_=(\$r)");
456449
}
457-
if (calculateParameterCount(m.signature) > 0) {
450+
if (m.method.parameterTypes.length > 0) {
458451
stringBuilder.append(getStaticSuperMethodName(m.methodName) + "(this," + Constants.ORIGINCLASS + ",\$\$);");
459452
} else {
460453
stringBuilder.append(getStaticSuperMethodName(m.methodName) + "(this," + Constants.ORIGINCLASS + ");");

auto-patch-plugin/src/main/groovy/robust/gradle/plugin/AutoPatchTransform.groovy

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ import java.util.zip.ZipOutputStream
2424
* AutoPatchTransform generate patch dex
2525
*/
2626
class AutoPatchTransform extends Transform implements Plugin<Project> {
27-
private
28-
static String zipCommand = " zip -r " + Constants.ZIP_FILE_NAME + " com -x \"*/\\.*\" -x \"\\.*\"";
2927
private
3028
static String dex2SmaliCommand;
3129
private
@@ -150,8 +148,7 @@ class AutoPatchTransform extends Transform implements Plugin<Project> {
150148
}
151149
def zipPatchClassesFile(){
152150
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(Config.robustGenerateDirectory+ Constants.ZIP_FILE_NAME));
153-
zipAllPatchClasses(Config.robustGenerateDirectory+"com","",zipOut);
154-
151+
zipAllPatchClasses(Config.robustGenerateDirectory+Config.patchPackageName.substring(0,Config.patchPackageName.indexOf(".")),"",zipOut);
155152
zipOut.close();
156153

157154
}

auto-patch-plugin/src/main/java/com/meituan/robust/utils/SmaliUitils.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,12 @@ private List<String> getPackNameFromSmaliLine(String line) {
222222
return packageNameList;
223223

224224
}
225+
public static void main(String[] args) {
226+
SmaliUitils smaliUitils=new SmaliUitils();
227+
smaliUitils.getObscuredMethodSignure("invokeReflectConstruct(Ljava/lang/String;[Ljava/lang/Object;[Ljava/lang/Class;)Ljava/lang/Object;","com.meituan.second");
228+
}
229+
private String getObscuredMethodSignure(final String line, String className) {
225230

226-
private String getObscuredMethodSignure(final String line, String className) {
227231
if (className.endsWith(Constants.PATCH_SUFFIX) && Config.modifiedClassNameList.contains(className.substring(0, className.indexOf(Constants.PATCH_SUFFIX)))) {
228232
className = className.substring(0, className.indexOf(Constants.PATCH_SUFFIX));
229233
}
@@ -232,9 +236,15 @@ private String getObscuredMethodSignure(final String line, String className) {
232236
String parameter = line.substring(line.indexOf("("), line.indexOf(")") + 1);
233237
int endIndex = line.indexOf(")");
234238
String methodSigure = line.substring(0, endIndex + 1);
239+
//invokeReflectConstruct(Ljava/lang/String;[Ljava/lang/Object;[Ljava/lang/Class;)Ljava/lang/Object;
240+
boolean isArray=false;
235241
for (int index = line.indexOf("(") + 1; index < endIndex; index++) {
236-
if (Constants.PACKNAME_START.equals(String.valueOf(methodSigure.charAt(index))) && methodSigure.indexOf(Constants.PACKNAME_END) != -1) {
242+
if (Constants.PACKNAME_START.equals(String.valueOf(methodSigure.charAt(index))) && methodSigure.contains(Constants.PACKNAME_END)) {
237243
methodSignureBuilder.append(methodSigure.substring(index + 1, methodSigure.indexOf(Constants.PACKNAME_END, index)).replaceAll("/", "\\."));
244+
if(isArray){
245+
methodSignureBuilder.append("[]");
246+
isArray=false;
247+
}
238248
index = methodSigure.indexOf(";", index);
239249
methodSignureBuilder.append(",");
240250
}
@@ -271,9 +281,17 @@ private String getObscuredMethodSignure(final String line, String className) {
271281
default:
272282
break;
273283
}
284+
if(isArray){
285+
methodSignureBuilder.append("[]");
286+
isArray=false;
287+
}
274288
methodSignureBuilder.append(",");
275289
}
276290

291+
if (Constants.ARRAY_TYPE.equals(String.valueOf(methodSigure.charAt(index)))) {
292+
isArray=true;
293+
}
294+
277295
}
278296

279297
List<String> returnTypeList = gePackageNameFromSmaliLine(line.substring(endIndex + 1));
@@ -283,6 +301,7 @@ private String getObscuredMethodSignure(final String line, String className) {
283301
String obscuredMethodSignure = methodSignureBuilder.toString();
284302
String obscuredMethodName = getObscuredMemberName(className, ReadMapping.getInstance().getMethodSignureWithReturnType(returnTypeList.get(0), obscuredMethodSignure));
285303
obscuredMethodSignure = obscuredMethodName + parameter;
304+
// System.out.println("getObscuredMethodSignure is "+obscuredMethodSignure.substring(0, obscuredMethodSignure.indexOf("(")) + parameter);
286305
return obscuredMethodSignure.substring(0, obscuredMethodSignure.indexOf("(")) + parameter;
287306
}
288307

autopatchbase/src/main/java/com/meituan/robust/Constants.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ public class Constants {
4848
public static Class AddAnnotationClass = null;
4949

5050
public final static String[] LIB_NAME_ARRAY = {"baksmali-2.1.2.jar", "smali-2.1.2.jar", "dx.jar"};
51-
public static final String PACKNAME_START = "L";
5251
public static final String PACKNAME_END = ";";
5352
public final static String PRIMITIVE_TYPE = "ZCBSIJFDV";
53+
public final static String ARRAY_TYPE = "[";
5454
public final static char OBJECT_TYPE = 'L';
55+
public static final String PACKNAME_START = String.valueOf(OBJECT_TYPE);
5556
public static final Boolean OBSCURE = true;
5657
// public static final Boolean OBSCURE = false;
5758
// public static final Boolean isLogging = false;

0 commit comments

Comments
 (0)