最近翻著網(wǎng)頁上的例子很多都是拿微信來作為例子,于是我也入鄉(xiāng)隨俗,來學(xué)習(xí)學(xué)習(xí)
先給個將要做的事情的截圖 對列表的長按事件進行響應(yīng)

列表的長按事件
首先打開cmd 輸入 adb shell dumpsys activity top
你會得看到當(dāng)前界面布局層級,然后往下翻著看 你會發(fā)現(xiàn)一個很熟悉的東西

于是有了目標(biāo)了 開始編碼
/**
* 觀察聊天界面的時候發(fā)現(xiàn)了 ConversationWithAppBrandListView 組建
* 得到了 item data為com.tencent.mm.storage.ae
* adapter address-> com.tencent.mm.ui.conversation.g
* @param applicationContext
* @param classLoader
*/
private void hookConversationWithAppBrandListView(final Context applicationContext, final ClassLoader classLoader) {
XposedBridge.log("Demo: hookListView");
XposedHelpers.findAndHookMethod("com.tencent.mm.ui.conversation.ConversationWithAppBrandListView",
classLoader,
"setAdapter",
ListAdapter.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
ListAdapter adapter = (ListAdapter) param.args[0];
XposedBridge.log("Demo: hookListView adapter address-> " + adapter.toString());
Log.e("Demo: hookListView", " adapter address-> " + adapter.toString());
int count = adapter.getCount();
Log.e("Demo: hookListView->", "ConversationWithAppBrandListView has " + count + " child");
for (int i = 0; i < count; i++) {
Object s = adapter.getItem(i);
Log.e("Demo: hookListView->", "item data -> " + JSONObject.toJSONString(s));
}
}
});
}
以上log日志你可以看到列表的數(shù)據(jù) 和 adapter所在的位置com.tencent.mm.ui.conversation.g 這個是關(guān)鍵點
定位到 com.tencent.mm.ui.conversation.g 發(fā)現(xiàn)它還有一個實現(xiàn)類
public final class g extends f<String, ae> implements b
定位過去
public interface b {
void a(int i, m mVar, Object obj);
}

看到?jīng)]有關(guān)聯(lián)字樣 Conversation 我猜想他們之間是有關(guān)聯(lián)的 直接搜索關(guān)鍵字onItemLongClick

通過 BizChatConversationUI$a$17 關(guān)聯(lián)到了 com.tencent.mm.ui.widget.i 類下的
public final void a(View view, int i, long j, OnCreateContextMenuListener onCreateContextMenuListener, p$d p_d, int i2, int i3) {
this.snI = p_d;
this.zew = view;
cAT();
this.snJ.clear();
ContextMenuInfo adapterContextMenuInfo = new AdapterContextMenuInfo(view, i, j);
onCreateContextMenuListener.onCreateContextMenu(this.snJ, view, adapterContextMenuInfo);
for (MenuItem menuItem : this.snJ.yAS) {
((o) menuItem).yAV = adapterContextMenuInfo;
}
if (i2 == 0 && i3 == 0) {
bS(0, 0);
} else {
bS(i2, i3);
}
}
抱著試試的心態(tài) 寫了下面的代碼
/**
* 微信列表界面長按點擊事件
* 引用地址 com.tencent.mm.ui.bizchat.BizChatConversationUI$a$17
*
* @param applicationContext
* @param classLoader
*/
private void hookWxItemLongClick(final Context applicationContext, ClassLoader classLoader) {
Class<?> classIfExists = XposedHelpers.findClassIfExists("com.tencent.mm.ui.base.p$d", classLoader);
if (classIfExists == null) return;
XposedHelpers.findAndHookMethod("com.tencent.mm.ui.widget.i",
classLoader,
"a",
View.class,
int.class,
long.class,
View.OnCreateContextMenuListener.class,
classIfExists,
int.class,
int.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.e("Demo: hookWxItemLongClick->", param.args[1].toString() + "-" + param.args[5].toString() + "-" + param.args[6].toString());
}
});
}
功夫不負有心人,
04-23 12:35:45.287 9142-9142/com.tencent.mm E/Demo: hookWxItemLongClick->: 16-332-611
看到了這個log
其中在對com.tencent.mm.ui.widget.i進行hook的時候遇到了一些小問題,就是我標(biāo)題所述的參數(shù)問題
第一是數(shù)據(jù)類型:
應(yīng)為在做安卓應(yīng)用層的時候 int.class 這樣的寫法是不被允許的 一般都是使用他們的包裝類型Integer.class 所以我直接參數(shù)類型寫的Integer.class 會導(dǎo)致hook找不到對應(yīng)的方法 需要更換為 int.class 做到與目標(biāo)方法參數(shù)對應(yīng)才行 Long類型也是同理
第二是內(nèi)部方法:
在對com.tencent.mm.ui.widget.i進行hook的時候有個內(nèi)部方法com.tencent.mm.ui.base.p$d 需要用反射拿到類型
希望能幫助遇到同樣情況的小伙伴