package com.taobao.dexposed; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; import com.taobao.android.dexposed.XC_MethodHook; import com.taobao.android.dexposed.DexposedBridge; import com.taobao.patch.PatchMain; import com.taobao.patch.PatchResult; import java.io.File; public class MainActivity extends Activity { static { // load xposed lib for hook. try { if (android.os.Build.VERSION.SDK_INT == 22){ System.loadLibrary("dexposed_l51"); } else if (android.os.Build.VERSION.SDK_INT > 19 && android.os.Build.VERSION.SDK_INT <= 21){ System.loadLibrary("dexposed_l"); } else if (android.os.Build.VERSION.SDK_INT > 14){ System.loadLibrary("dexposed"); } } catch (Throwable e) { e.printStackTrace(); } } private boolean isSupport = false; private boolean isLDevice= false; private TextView mLogContent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLogContent = (TextView) (this.findViewById(R.id.log_content)); // check device if support and auto load libs isSupport = true; isLDevice = android.os.Build.VERSION.SDK_INT >= 20; } //Hook system log click public void hookSystemLog(View view) { if (isSupport) { DexposedBridge.findAndHookMethod(isLDevice ? this.getClass(): Log.class, isLDevice ? "showLog" : "d", String.class, String.class, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam arg0) throws Throwable { String tag = (String) arg0.args[0]; String msg = (String) arg0.args[1]; mLogContent.setText(tag + "," + msg); } }); if (isLDevice) { showLog("dexposed", "It doesn't support AOP to system method on ART devices"); } else { Log.d("dexposed", "Logs are redirected to display here"); } } else { mLogContent.setText("This device doesn't support dexposed!"); } } private void showLog(String tag, String msg) { Log.d(tag, msg); } // Hook choreographer click public void hookChoreographer(View view) { Log.d("dexposed", "hookChoreographer button clicked."); if (isSupport && !isLDevice) { ChoreographerHook.instance().start(); } else { showLog("dexposed", "This device doesn't support this!"); } } // Run patch apk public void runPatchApk(View view) { Log.d("dexposed", "runPatchApk button clicked."); if (isLDevice) { showLog("dexposed", "It doesn't support this function on L device."); return; } if (!isSupport) { Log.d("dexposed", "This device doesn't support dexposed!"); return; } File cacheDir = getExternalCacheDir(); if(cacheDir != null){ String fullpath = cacheDir.getAbsolutePath() + File.separator + "patch.apk"; PatchResult result = PatchMain.load(this, fullpath, null); if (result.isSuccess()) { Log.e("Hotpatch", "patch success!"); } else { Log.e("Hotpatch", "patch error is " + result.getErrorInfo()); } } showDialog(); } private void showDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Dexposed sample") .setMessage( "Please clone patchsample project to generate apk, and copy it to \"/Android/data/com.taobao.dexposed/cache/patch.apk\"") .setPositiveButton("ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }).create().show(); } }