手动创建Context

本文介绍如何在非常规Android程序环境中手动创建Context对象,通过反射调用ActivityThread和ContextImpl的私有方法,实现在Androidshell下执行Java代码时获取Context的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目需要在 Android shell 下执行 Java 代码,很多时候需要用到Context,不是常规的 Android 程序执行没办法直接获取到 Context 于是在经过一番阅读 Android 源码之后找到解决方案,手动创建一个Context。
先看 Context.java 的源码,发现是一个抽象类,具体实现是在 ContextImpl.java
创建 ContextImpl 的方法如下:

static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
                null);
        context.setResources(packageInfo.getResources());
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetrics());
        return context;
    }

是一个私有静态方法,有一个 ActivityThread 参数,这样的话只需要反射得到它并给他一个参数就可以了
继续看 ActivityThread 的实现,发现有个静态方法 systemMain:

public static ActivityThread systemMain() {
        // The system process on low-memory devices do not get to use hardware
        // accelerated drawing, since this can add too much overhead to the
        // process.
        if (!ActivityManager.isHighEndGfx()) {
            ThreadedRenderer.disable(true);
        } else {
            ThreadedRenderer.enableForegroundTrimming();
        }
        ActivityThread thread = new ActivityThread();
        thread.attach(true);
        return thread;
    }

只需要反射执行它就能拿到 ActivityThread 创建的实例,这样的话 获取 ContextImpl 的方法和参数都拿到了,只需要反射执行就可以了,代码如下:

				Looper.prepareMainLooper();
				
				Class<?> ActivityThread = Class.forName("android.app.ActivityThread");
				Method systemMain = ActivityThread.getDeclaredMethod("systemMain");
				
				Object object = systemMain.invoke(null);
				
				Class<?> ContextImpl  = Class.forName("android.app.ContextImpl");
				Method createSystemContext = ContextImpl.getDeclaredMethod("createSystemContext", ActivityThread);
				createSystemContext.setAccessible(true);
				Context contextInstace = (Context)createSystemContext.invoke(null, object);
				Context context = contextInstace.createPackageContext("com.tanzui.test", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值