美文网首页
Xposed框架入门

Xposed框架入门

作者: small瓜瓜 | 来源:发表于2020-05-14 16:51 被阅读0次

    目录

    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));
                        }
                    });
        }
    
    }
    

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



    到此全部完成啦

    相关文章

      网友评论

          本文标题:Xposed框架入门

          本文链接:https://www.haomeiwen.com/subject/pyxtohtx.html