刚发现的一个反编译神器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<ActivityBoardBean> 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<ActivityBoardBean> 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反编译代码.