刚发现的一个反编译神器jadx,对比之前的apktool跟dex2jar,jadx胜在可读性好太多,apktool后的smali长的跟汇编语言一样,dex2jar产生的源码也经常出现奇奇怪怪的语法,让我理解不能.
jadx GitHub 地址:https://github.com/skylot/jadx
下载或克隆后,在目录下运行
./gradlew dist
结束后会生成build文件夹,我们需要的脚本文件就在build\jadx\bin下;
我们可以命令行运行jadx.bat脚本产生源码:
jadx -d out classes.dex
也可以打开jadx-gui.bat图形化界面查看源码;
图可能看不清,选一个代码量不大的类贴上看
package com.ddfun.a;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.ddfun.R;
import com.ddfun.activity.MyWebview;
import com.ddfun.model.ActivityBoardBean;
import com.ff.common.c.b;
import java.util.List;
public class a extends BaseAdapter {
List a;
public static class a implements OnClickListener {
ActivityBoardBean a;
TextView b;
TextView c;
ImageView d;
ImageView e;
ImageView f;
public void a(View view) {
this.f = (ImageView) view.findViewById(R.id.icon_iv);
this.d = (ImageView) view.findViewById(R.id.hot_iv);
this.e = (ImageView) view.findViewById(R.id.new_iv);
this.b = (TextView) view.findViewById(2131624086);
this.c = (TextView) view.findViewById(R.id.tv_time);
view.setTag(this);
view.setOnClickListener(this);
}
public void onClick(View view) {
a aVar = (a) view.getTag();
view.getContext().startActivity(MyWebview.a(view.getContext(), null, b.a(aVar.a.id), "activityboardtype", aVar.a.title));
}
}
public /* synthetic */ Object getItem(int i) {
return a(i);
}
public View getView(int i, View view, ViewGroup viewGroup) {
a aVar;
if (view == null) {
view = View.inflate(viewGroup.getContext(), R.layout.activity_board_list_item_lay, null);
a aVar2 = new a();
aVar2.a(view);
aVar = aVar2;
} else {
aVar = (a) view.getTag();
}
ActivityBoardBean a = a(i);
aVar.a = a;
aVar.b.setText(a.title);
aVar.c.setText(a.publish_date);
if (a.isHot()) {
if (aVar.d.getVisibility() != 0) {
aVar.d.setVisibility(0);
}
} else if (aVar.d.getVisibility() != 8) {
aVar.d.setVisibility(8);
}
if (a.isNew()) {
if (aVar.e.getVisibility() != 0) {
aVar.e.setVisibility(0);
}
} else if (aVar.e.getVisibility() != 8) {
aVar.e.setVisibility(8);
}
com.ff.imgloader.a.a().a(com.ff.imgloader.a.b(a.image), aVar.f, com.ff.imgloader.a.c, com.ff.imgloader.a.c, false);
return view;
}
public void a(List list) {
this.a = list;
notifyDataSetChanged();
}
public synchronized boolean b(List list) {
boolean z;
int i = 0;
z = false;
while (i < list.size()) {
boolean z2;
ActivityBoardBean activityBoardBean = (ActivityBoardBean) list.get(i);
if (this.a.contains(activityBoardBean)) {
z2 = z;
} else {
this.a.add(activityBoardBean);
z2 = true;
}
i++;
z = z2;
}
if (z) {
notifyDataSetChanged();
}
return z;
}
public int getCount() {
return this.a == null ? 0 : this.a.size();
}
public ActivityBoardBean a(int i) {
return (ActivityBoardBean) this.a.get(i);
}
public long getItemId(int i) {
return 0;
}
}
大家可以看到,可读性是不是非常高,这还是在代码混淆的情况下.我们不开启代码混淆来看看:
package com.ddfun.adapter;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.ddfun.R;
import com.ddfun.activity.MyWebview;
import com.ddfun.model.ActivityBoardBean;
import com.ff.common.http.MyHttpClient;
import com.ff.imgloader.ImageLoader;
import java.util.List;
public class ActivityBoardListAdapter extends BaseAdapter {
List list;
public static class Holder implements OnClickListener {
ImageView hot_iv;
ImageView icon_iv;
ActivityBoardBean item;
TextView name_tv;
ImageView new_iv;
TextView tv_time;
public void initView(View v) {
this.icon_iv = (ImageView) v.findViewById(R.id.icon_iv);
this.hot_iv = (ImageView) v.findViewById(R.id.hot_iv);
this.new_iv = (ImageView) v.findViewById(R.id.new_iv);
this.name_tv = (TextView) v.findViewById(2131624086);
this.tv_time = (TextView) v.findViewById(R.id.tv_time);
v.setTag(this);
v.setOnClickListener(this);
}
public void onClick(View v) {
Holder holder = (Holder) v.getTag();
v.getContext().startActivity(MyWebview.getStartIntent(v.getContext(), null, MyHttpClient.getActivityBoardUrl(holder.item.id), MyWebview.ACTIVITYBOARDTYPE, holder.item.title));
}
}
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
convertView = View.inflate(parent.getContext(), R.layout.activity_board_list_item_lay, null);
holder = new Holder();
holder.initView(convertView);
} else {
holder = (Holder) convertView.getTag();
}
ActivityBoardBean item = getItem(position);
holder.item = item;
holder.name_tv.setText(item.title);
holder.tv_time.setText(item.publish_date);
if (item.isHot()) {
if (holder.hot_iv.getVisibility() != 0) {
holder.hot_iv.setVisibility(0);
}
} else if (holder.hot_iv.getVisibility() != 8) {
holder.hot_iv.setVisibility(8);
}
if (item.isNew()) {
if (holder.new_iv.getVisibility() != 0) {
holder.new_iv.setVisibility(0);
}
} else if (holder.new_iv.getVisibility() != 8) {
holder.new_iv.setVisibility(8);
}
ImageLoader.getInstance().loadIcon(ImageLoader.getPrefixedUrl(item.image), holder.icon_iv, ImageLoader.PREVIEWPICSIZE, ImageLoader.PREVIEWPICSIZE, false);
return convertView;
}
public void setData(List l) {
this.list = l;
notifyDataSetChanged();
}
public synchronized boolean addData(List l) {
boolean needNotify;
needNotify = false;
for (int i = 0; i < l.size(); i++) {
ActivityBoardBean bean = (ActivityBoardBean) l.get(i);
if (!this.list.contains(bean)) {
this.list.add(bean);
needNotify = true;
}
}
if (needNotify) {
notifyDataSetChanged();
}
return needNotify;
}
public int getCount() {
return this.list == null ? 0 : this.list.size();
}
public ActivityBoardBean getItem(int position) {
return (ActivityBoardBean) this.list.get(position);
}
public long getItemId(int position) {
return 0;
}
}
这个图截的是跟图一同一个类,我用txt打开的.大家可以看到,是不是跟源码基本一样了,以后可以选择apktool+jadx来使用,apktool反编译资源文件,清单文件;jadx反编译代码.