Xposed框架入门

目录

  1. Xposed框架是什么
  2. 如何安装Xposed
  3. 为测试Xposed功能编写一个测试app
  4. 编写Xposed插件
  5. 编写最后逻辑功能

1.Xposed框架是什么

Xposed框架是一款开源框架,其功能是可以在不修改APK的情况下影响程序运行(修改系统)的框架服务,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。Xposed 就好比是 Google 模块化手机的主体,只是一个框架的存在,在添加其他功能模块(Modules)之前,发挥不了什么作用,但是没了它也不行。也正因为如此,Xposed 具有比较高的可定制化程度。Xposed 则允许用户自选模块对手机功能进行自定义扩充。(但是划重点,手机必须root,当然你也可以选择使用“太极”)

2. 如何安装Xposed

  • 手机安装Xposed`Installer`,它是一个`Xposed`下载安装器,因为`Xposed`是要对应android系统,同时还要检查安装环境等,使用XposedInstaller即可轻松搞定

    没有安装就如上图所示,点击“安装/更新”,``XposedInstaller将会自动安装Xposed

    安装重启完成后的界面如上图所示

3. 为测试Xposed功能编写一个测试app

现在Xposed安装完成了,为了测试插件功能,这里我们开始编写一个测试用的app
如下:


只有一个activity,布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/showTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name" />

</LinearLayout>
package cn.infomany.`Xposed`test;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private Button button;
    private TextView showTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.button);
        showTextView = findViewById(R.id.showTextView);
        changeText("hi,时间");
    }

    private void changeText(String s) {
        showTextView.setText(s);
    }
}

测试app东西很少,主要为了测试。启动后如图:


4. 编写Xposed插件

开始编写插件吧,首先我们像创建一个普通的安卓项目一样。使用android studio创建一个安卓项目
为了让Xposed能识别这是一个Xposed的插件。我们需要在AndroidManifest.xml中进行配置,添加三个meta-data,如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.infomany.`Xposed`study">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- 表明这是一个`Xposed`插件 -->
        <meta-data
            android:name="`Xposed`module"
            android:value="true" /> 
       <!-- 指定`Xposed`的最小版本 -->
        <meta-data
            android:name="`Xposed`minversion"
            android:value="30+" />
        <!-- 插件的描述 -->
        <meta-data
            android:name="`Xposed`description"
            android:value="`Xposed`插件开发测试" />
    </application>

</manifest>

现在把我们的插件安装好就可以在``XposedInstaller的模块界面中看到手机中的所有的Xposed模块,我们编写的模块已经在列表中了,将其启动就可以

这个时候我们的插件是启动了,但是不会有反应,因为没有编写逻辑代码。
下面编写逻辑代码,编写一个HookLogic类,类名不重要,但是必须继承致类de.robv.android.Xposed.IXposedHookLoadPackage,并实现handleLoadPackage方法,首先要导入 Xposed库,在build.gradle(Module.app)中依赖dependencies下添加compileOnly 'de.robv.android.Xposed:api:82'


下面是HookLogic的代码:

public class HookLogic implements I`Xposed`HookLoadPackage {

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {

        `Xposed`Bridge.log("HookLogic >> current package:" + lpparam.packageName);
   }
}

handleLoadPackage方法会在每一个app第一次启动时调用,为了然Xposed框架知道,HookLogic入口,就像是main方法一样,我们要创建assets资源目录,然后编写``Xposed_init文件,文件中只需要填写HookLogic类的全类名既可,如下:



到此我们就可以重新安装我们的插件到手机上,然后看看效果了。(安装后, 手机通知栏Xposed会提示有插件更新,选择重启,有重启设备软重启。这个时候,如果是真机就选择重启设备模拟器就选择软重启

重启后我们就可以看到日志中打印我们的信息,因为使用的是XposedBridge.log打印日志,所以可以在日志中看到:

5. 编写最后逻辑功能

本插件的目的是:

  • 获取textview和button的实例
  • 修改textview的字体属性
  • 为button添加事件
    好,我们修改HookLogic类,实现上面的功能,代码如下:
package cn.infomany.`Xposed`study;

import android.graphics.Color;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Random;

import de.robv.android.`Xposed`.I`Xposed`HookLoadPackage;
import de.robv.android.`Xposed`.XC_MethodHook;
import de.robv.android.`Xposed`.`Xposed`Bridge;
import de.robv.android.`Xposed`.`Xposed`Helpers;
import de.robv.android.`Xposed`.callbacks.XC_LoadPackage;

public class HookLogic implements I`Xposed`HookLoadPackage {

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {

        String testClassName = "cn.infomany.`Xposed`test.MainActivity";

        `Xposed`Bridge.log("HookLogic >> current package:" + lpparam.packageName);
        if (!testClassName.startsWith(lpparam.packageName)) {
            return;
        }

        `Xposed`Bridge.log("HookLogic >> 进来了");

        `Xposed`Helpers.findAndHookMethod(testClassName,
                lpparam.classLoader,
                "changeText", String.class
                , new XC_MethodHook() {

                    private Button button;

                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        super.beforeHookedMethod(param);
                        Field field = param.thisObject.getClass().getDeclaredField("showTextView");
                        field.setAccessible(true);
                        final TextView showTextView = (TextView) field.get(param.thisObject);
                        showTextView.setText("我是`Xposed`插件");
                        showTextView.setTextColor(Color.parseColor("#d52121"));
                        showTextView.setTextSize(30);

                        Field buttonField = param.thisObject.getClass().getDeclaredField("button");
                        buttonField.setAccessible(true);
                        button = (Button) buttonField.get(param.thisObject);
                        button.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                int i = new Random().nextInt(100);
                                showTextView.setText("我是`Xposed`插件" + i);
                            }
                        });

                    }

                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        super.afterHookedMethod(param);
                        button.performClick();
                        `Xposed`Bridge.log("HookLogic >> " + Arrays.asList(param.args));
                    }
                });
    }

}

到此我们功能就全部实现了,重新安装插件到手机上。



到此全部完成啦

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,000评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,745评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,561评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,782评论 1 298
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,798评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,394评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,952评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,852评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,409评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,483评论 3 341
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,615评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,303评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,979评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,470评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,571评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,041评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,630评论 2 359