不安装游戏apk直接启动法

原文地址:http://blog.zhourunsheng.com/2011/09/%E6%8E%A2%E7%A7%98%E8%85%BE%E8%AE%AFandroid%E6%89%8B%E6%9C%BA%E6%B8%B8%E6%88%8F%E5%B9%B3%E5%8F%B0%E4%B9%8B%E4%B8%8D%E5%AE%89%E8%A3%85%E6%B8%B8%E6%88%8Fapk%E7%9B%B4%E6%8E%A5%E5%90%AF%E5%8A%A8%E6%B3%95/?utm_source=rss&utm_medium=rss&utm_campaign=%25e6%258e%25a2%25e7%25a7%2598%25e8%2585%25be%25e8%25ae%25afandroid%25e6%2589%258b%25e6%259c%25ba%25e6%25b8%25b8%25e6%2588%258f%25e5%25b9%25b3%25e5%258f%25b0%25e4%25b9%258b%25e4%25b8%258d%25e5%25ae%2589%25e8%25a3%2585%25e6%25b8%25b8%25e6%2588%258fapk%25e7%259b%25b4%25e6%258e%25a5%25e5%2590%25af%25e5%258a%25a8%25e6%25b3%2595


前言

相信这样一个问题,大家都不会陌生,

“有什么的方法可以使Android的程序APK不用安装,而能够直接启动”。

发现最后的结局都是不能实现这个美好的愿望,而腾讯Android手机游戏平台却又能实现这个功能,下载的连连看,五子棋都没有安装过程,但是都能直接运行,这其中到底有什么“玄机”呢,也有热心童鞋问过我这个问题,本文就为大家来揭开这个谜团。

重要说明

在实践的过程中大家都会发现资源引用的问题,这里重点声明两点:
1. 资源文件是不能直接inflate的,如果简单的话直接在程序中用代码书写。
2. 资源文件是不能用R来引用的,因为上下文已经不同了,腾讯的做法是将资源文件打包(*.pak文件和APK打包在一起),虽然APK是没有进行安装,但是资源文件是另外解压到指定文件夹下面的,然后将文件夹的地址传给了第三方应用程序,这样第三方应用程序通过File的inputstream流还是可以读取和使用这些资源的。

实践

我实现了一个小小的Demo,麻雀虽小五脏俱全,为了突出原理,我就尽量简化了程序,通过这个实例来让大家明白后台的工作原理。

  1. 下载demo的apk程序apks,其中包括了两个apk,分别是A和B
  2. 这两个APK可分别安装和运行,A程序界面只显示一个Button,B程序界面会动态显示当前的时间
  3. 下面的三幅图片分别为直接启动运行A程序(安装TestA.apk),直接启动运行B程序(安装TestB.apk)和由A程序动态启动B程序(安装TestA.apk,TestB.apk不用安装,而是放在/mnt/sdcard/目录中,即 SD卡上)的截图,细心的同学可以停下来观察一下他们之间的不同
  4. 后两幅图片的不同,也即Title的不同,则解释出了我们将要分析的后台实现原理的机制

实现原理

最能讲明白道理的莫过于源码了,下面我们就来分析一下A和B的实现机制,首先来分析TestA.apk的主要代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    @Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);Button btn = (Button) findViewById(R.id.btn);btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Bundle paramBundle = new Bundle();paramBundle.putBoolean("KEY_START_FROM_OTHER_ACTIVITY", true);String dexpath = "/mnt/sdcard/TestB.apk";String dexoutputpath = "/mnt/sdcard/";LoadAPK(paramBundle, dexpath, dexoutputpath);}});}

代码解析:这就是OnCreate函数要做的事情,装载view界面,绑定button事件,大家都熟悉了,还有就是设置程序B的放置路径,因为我程序中代码是从/mnt/sdcard/TestB.apk中动态加载,这也就是为什么要让大家把TestB.apk放在SD卡上面的原因了。关键的函数就是最后一个了LoadAPK,它来实现动态加载B程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    public void LoadAPK(Bundle paramBundle, String dexpath, String dexoutputpath) {ClassLoader localClassLoader = ClassLoader.getSystemClassLoader();DexClassLoader localDexClassLoader = new DexClassLoader(dexpath,dexoutputpath, null, localClassLoader);try {PackageInfo plocalObject = getPackageManager().getPackageArchiveInfo(dexpath, 1);if ((plocalObject.activities != null)&& (plocalObject.activities.length > 0)) {String activityname = plocalObject.activities[0].name;Log.d(TAG, "activityname = " + activityname);Class localClass = localDexClassLoader.loadClass(activityname);Constructor localConstructor = localClass.getConstructor(new Class[] {});Object instance = localConstructor.newInstance(new Object[] {});Log.d(TAG, "instance = " + instance);Method localMethodSetActivity = localClass.getDeclaredMethod("setActivity", new Class[] { Activity.class });localMethodSetActivity.setAccessible(true);localMethodSetActivity.invoke(instance, new Object[] { this });Method methodonCreate = localClass.getDeclaredMethod("onCreate", new Class[] { Bundle.class });methodonCreate.setAccessible(true);methodonCreate.invoke(instance, new Object[] { paramBundle });}return;} catch (Exception ex) {ex.printStackTrace();}}

代码解析:这个函数要做的工作如下:加载B程序的APK文件,通过类加载器DexClassLoader来解析APK文件,这样会在SD卡上面生成一个同名的后缀为dex的文件,例如/mnt/sdcard/TestB.apk==>/mnt/sdcard/TestB.dex,接下来就是通过java反射机制,动态实例化B中的Activity对象,并依次调用了其中的两个函数,分别为setActivity和onCreate.看到这里,大家是不是觉得有点奇怪,Activity的启动函数是onCreate,为什么要先调用setActivity,而更奇怪的是setActivity并不是系统的函数,确实,那是我们自定义的,这也就是核心的地方。

好了带着这些疑问,我们再来分析B程序的主代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class TestBActivity extends Activity {private static final String TAG = "TestBActivity";private Activity otherActivity;@Overridepublic void onCreate(Bundle savedInstanceState) {boolean b = false;if (savedInstanceState != null) {b = savedInstanceState.getBoolean("KEY_START_FROM_OTHER_ACTIVITY", false);if (b) {this.otherActivity.setContentView(new TBSurfaceView(this.otherActivity));}}if (!b) {super.onCreate(savedInstanceState);// setContentView(R.layout.main);setContentView(new TBSurfaceView(this));}}public void setActivity(Activity paramActivity) {Log.d(TAG, "setActivity..." + paramActivity);this.otherActivity = paramActivity;}
}

代码解析:看完程序B的实现机制,大家是不是有种恍然大悟的感觉,这根本就是“偷梁换柱”嘛,是滴,程序B动态借用了程序A的上下文执行环境,这也就是上面后两幅图的差异,最后一幅图运行的是B的程序,但是title表示的却是A的信息,而没有重新初始化自己的,实际上这也是不可能的,所以有些童鞋虽然通过java的反射机制,正确呼叫了被调程序的onCreate函数,但是期望的结果还是没有出现,原因就是这个上下文环境没有正确建立起来,但是若通过startActivity的方式来启动APK的话,android系统会替你建立正确的执行时环境,所以就没问题。至于那个TBSurfaceView,那就是自定义的一个view画面,动态画当前的时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public class TBSurfaceView extends SurfaceView implements Callback, Runnable {private SurfaceHolder sfh;private Thread th;private Canvas canvas;private Paint paint;public TBSurfaceView(Context context) {super(context);th = new Thread(this);sfh = this.getHolder();sfh.addCallback(this);paint = new Paint();paint.setAntiAlias(true);paint.setColor(Color.RED);this.setKeepScreenOn(true);}public void surfaceCreated(SurfaceHolder holder) {th.start();}private void draw() {try {canvas = sfh.lockCanvas();if (canvas != null) {canvas.drawColor(Color.WHITE);canvas.drawText("Time: " + System.currentTimeMillis(), 100,100, paint);}} catch (Exception ex) {ex.printStackTrace();} finally {if (canvas != null) {sfh.unlockCanvasAndPost(canvas);}}}public void run() {while (true) {draw();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}public void surfaceDestroyed(SurfaceHolder holder) {}
}

腾讯游戏平台解析

说了这么多,都是背景,O(∩_∩)O哈哈~

其实腾讯游戏平台就是这么个实现原理,我也是通过它才学习到这种方式的,还得好好感谢感谢呢。

腾讯Android游戏平台的游戏分成两类,第一类是腾讯自主研发的,像斗地主,五子棋,连连看什么的,所以实现机制就如上面的所示,A代表游戏大厅,B代表斗地主类的小游戏。第二类是第三方软件公司开发的,可就不能已这种方式来运作了,毕竟腾讯不能限制别人开发代码的方式啊,所以腾讯就开放了一个sdk包出来,让第三方应用可以和游戏大厅相结合,具体可参见QQ游戏中心开发者平台,但这同时就损失了一个优点,那就是第三方开发的游戏要通过安装的方式才能运行。

结论

看到这里,相信大家都比较熟悉这个背后的原理了吧,也希望大家能提供更好的反馈信息!

程序源码下载source


转载于:https://www.cnblogs.com/WIT-Evan/archive/2013/05/17/7291434.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/274242.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

web字体设置成平方字体_Web字体正确完成

web字体设置成平方字体When using web fonts we must carefully avoid its hidden pitfalls. To do this designers, frontend developers, DevOps, and authors each have a role to play in creating a great end-user experience.使用网络字体时,必须小心避免其隐…

Android客户端打包方案分享

基本介绍 Android应用的自动化打包是应用持续集成以及多渠道发布的基础。当前Android客户端自动化打包的主要有两种方式,Ant和Maven。两种方式本质上都是调用Android SDK里面提供的工具,不过各自有各自的特点。 1. Ant脚本 好处:开发成本较低…

sql注入修复方法是_旧的方法是修复我们可以看到的内容。

sql注入修复方法是When envisioning the futurestate of a company or a service, we’re usually faced with the challenge of designing for a customer that doesn’t exist yet. What do we mean by this? Well, they exist in the obvious sense, they’re just not ‘t…

library听证会_听证会

library听证会My Initial Experience with a Screen Reader我对屏幕阅读器的初步体验 As a new web developer, I have been learning to make my sites visually appealing but still be accessible, and all-in-all, it’s been going decent. I’ve been including cool ic…

jsoup测试例子

1、测试代码 import java.io.File; import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; public class Test { public static void main(String[] args) { Test t new Test(); t.parseUrl(); } publ…

ux和ui_他们说,以UX / UI设计师的身份加入一家初创公司。 他们说,这会很有趣。

ux和uiSure, working in a startup environment sounds fun. The stories of flexibility and freedom that it entails spark curiosity into people’s minds, making it enticing to explore a career in the startup scene. In reality, working in a startup just present…

程序员在囧途

程序员在囧途:http://www.shenyisyn.org/2013/05/21/cxyzhc.htm转载于:https://www.cnblogs.com/Qiaoyq/archive/2013/05/22/3092904.html

架构师之路 扩充字段_扩大您作为设计师的业务影响力的四个基础

架构师之路 扩充字段While catching up with my designer friends during these days of quarantine, a common topic surfaced in all our conversations despite the different countries, cultures, companies, seniority levels, and paths in the field: 在这些隔离日中与…

android之隐式intent调用

直接上代码 MainActivity.java 1 package com.example.test1;2 3 import android.app.Activity;4 import android.content.Intent;5 import android.net.Uri;6 import android.os.Bundle;7 import android.view.View;8 import android.view.View.OnClickListener;9 import andr…

webflow_Webflow是否适合开发人员? 我的经验

webflowThe biggest problem with site builders is the code they generate is usually garbage. As I’ve recently discovered, this isn’t the case with 网站建设者最大的问题是他们生成的代码通常是垃圾。 正如我最近发现的,情况并非如此 Webflow, and alth…

1.蛋疼上路

开博客了! 感觉会是很花时间的事。。转载于:https://www.cnblogs.com/-dante-/archive/2013/05/26/3099789.html

您的UX库不只是书籍

hp ux 密码不过期Looking back on past self, one thing I wish I’d realised is the importance of keeping notes of everything.回顾过去的自我,我希望我意识到的一件事是记录所有事情的重要性。 This means everything interesting I’ve read and written; e…

编译器错误 CS1026

http://technet.microsoft.com/zh-cn/library/tc5zwdf7%28vvs.80%29转载于:https://www.cnblogs.com/Peter-Youny/archive/2013/05/26/3099808.html

交互设计精髓_设计空间的精髓

交互设计精髓重点 (Top highlight)什么是空间? (What is Space?) Space is the dimension of height, depth and width within which all things exist and move. Space or Empty space or White space or Negative space are alias given to describe intensional…

软件过程软件Scrum敏捷开发

在写这篇文章之前,xxx已经写过了几篇关于改软件过程软件主题的文章,想要了解的朋友可以去翻一下之前的文章 1、什么是软件进程? 软件进程是为了建造高质量软件所需实现的任务的框架,即形成软件产品的一系列步骤,它划定了实现各项任务任务步骤,包括了中间产品、资源…

ux和ui_UI和UX设计人员的47个关键课程

ux和ui重点 (Top highlight)This is a mega-list of the most critical knowledge for UI, UX, interaction, or product designers at any level.这是所有级别的UI,UX,交互或产品设计人员最关键的知识的大清单。 Many of these lessons are also appli…

深入理解Java内存模型(七)——总结

处理器内存模型 顺序一致性内存模型是一个理论参考模型,JMM和处理器内存模型在设计时通常会把顺序一致性内存模型作为参照。JMM和处理器内存模型在设计时会对顺序一致性模型做一些放松,因为如果完全按照顺序一致性模型来实现处理器和JMM,那么…

沉浸式ui设计_有助于沉浸的视频游戏UI —武器轮

沉浸式ui设计Many action-adventure games rely on the feeling of thrills via bullets, fire, grenade, more bullets, and gigantic booms. The way to enable all these is to offer a massive arsenal, from machetes to assault rifles all the way till bazookas.许多动…

HDU 3068 最长回文

Manacher算法练笔&#xff0c;O(n)求最长回文子串。 参考资料&#xff1a;http://blog.csdn.net/ggggiqnypgjg/article/details/6645824 http://www.felix021.com/blog/read.php?2040 后缀数组和拓展KMP也可以求&#xff0c;不过时间复杂度都是O(nlogn)。 1 #include <cstd…

ux设计师薪水_客户现在也是UX设计师

ux设计师薪水Some of you probably know by now, I’m not too fond of the monster the UX industry has become. It’s overblown, overcomplicated and often dishonest towards the clients. It’s also in itself undefined. (where is the E in Experience?)你们中的某些…