`
handsomeliuyang
  • 浏览: 314889 次
  • 性别: Icon_minigender_1
  • 来自: 益阳
社区版块
存档分类
最新评论

浅析QQGame

 
阅读更多

通过分析QQGame的项目,发现其存在两种方式:

1. 不安装游戏apk,直接启动

我这里只说其原理,详情讲查看:探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法

其原理是:

  1. 把apk里的class文件通过DexClassLoader把apk里的class文件全部加载到java虚拟机里,如果要使用其中的某个class时,就要使用反射来调用。

  2. 如果这个类是Activity的子类,那如何来启动,Activity的子类是由android系统来创建,处理方法是:把Activity的子类当做一个有着Activity相应接口的类,在项目里创建一个空的Activity类,其里面不做任何事情,只是用反射调用真正的Activity的方法,代码如下:

 

public class MainActivity extends Activity {
	private static final String TAG = "MainActivity";
	
	private Class mActivityClass;
	private Object mActivityInstance;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		Button btn = (Button) findViewById(R.id.btn);
		btn.setOnClickListener(new OnClickListener() {

			@Override
			public 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);
			}
		});
	}
	
	@Override
	protected void onStart() {
		super.onStart();
		try {
			Method method = mActivityClass.getDeclaredMethod(
					"onStart");
			method.setAccessible(true);
			method.invoke(mActivityInstance);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		try {
			Method method = mActivityClass.getDeclaredMethod(
					"onResume");
			method.setAccessible(true);
			method.invoke(mActivityInstance);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		try {
			Method method = mActivityClass.getDeclaredMethod(
					"onPause");
			method.setAccessible(true);
			method.invoke(mActivityInstance);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	protected void onStop() {
		super.onStop();
		try {
			Method method = mActivityClass.getDeclaredMethod(
					"onStop");
			method.setAccessible(true);
			method.invoke(mActivityInstance);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		try {
			Method method = mActivityClass.getDeclaredMethod(
					"onDestroy");
			method.setAccessible(true);
			method.invoke(mActivityInstance);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	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);
				mActivityClass = localClass;
				Constructor localConstructor = localClass
						.getConstructor(new Class[] {});
				Object instance = localConstructor.newInstance(new Object[] {});
				Log.d(TAG, "instance = " + instance);
				mActivityInstance = 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();
		}
	}
}

 

 从上面可以看到,由于我们不能像系统一样初始化Activity,所以只能用一个Activity做为了容器,来调用其Activity相应的生命周期方法。

在另外的Activity里,把显示的view设置到传过来的Activity里面,同时,所有要与系统交互的,都要通过传过来的activity对象,这个和我们最开始的那个框架差不多。

 

这样做的好处:

  1. 可以做到apk,不安装的情况下,就可以启动这个apk

  2. 对于qqgame,由于只有一个Activity,而且游戏的图片资源都是自己加载的,所以很适合用这种方式

不足之处:

  1. 不能把res里的资源文件交给系统来管理,也就是资源(图片等等),都要自己去sdcard里去读取,去维护。

  2. 如果有多个Activity时,就会很麻烦,由于只是把些类加载进来,但不能由系统来初始化,那些startActivity的方法基本上不能用(虽然可以模拟,但会有很多的问题)

  3. 由于有这种限制,所以QQ的项目里,现在还只有QQGame用了这种模式

 

2. 安装游戏apk,再进行启动

这种模式比较简单:

1. 不要用启动的Activity

2. 把第一个启动的Activity加一个约定的Catergory:

 

<category android:name="android.intent.category.XXXX" />

还后,在门户的项目里,对当前手机进行探测,看有多少个含有这个类别的Activity,可以进行显示出来了。

 

结论:

对了我们这种应用app的程序,用这种方式,会大大加大开发的复杂度,不过其第二种方法不错,但要变化着使用。

使用交叉推荐:

  1. 在每个不同的项目里,都加入对其他产品的推荐(同时,检测用户手机里已经安装过的apk)。

  2. 有一些功能,还可以让用户跳到其他的apk实现。

 

 

分享到:
评论
2 楼 hgzhss 2012-07-23  
Method localMethodSetActivity = localClass.getDeclaredMethod( 
                        "setActivity", new Class[] { Activity.class }); 
                localMethodSetActivity.setAccessible(true); 
                localMethodSetActivity.invoke(instance, new Object[] { this });

中的 setActivity 这方法 里面是什么内容呀 ,为什么我用不了这个东西,他不是Activity 的方法,应该是个自定义的方法,他是怎么实现的呀

如果这个是个自定义的方法 ,那他就不能任意的打开apk的 Activity
1 楼 down_data01 2012-03-15  
奇思妙想哦

相关推荐

    腾讯-QQGame后台架构简介

    QQGame是腾讯公司推出的一款在线游戏平台,它涵盖了多种类型的游戏,为用户提供丰富的娱乐体验。QQGame的后台架构是支撑其稳定运行的关键所在,这里我们将深入探讨这一话题。 首先,我们要理解后台架构的重要性。在...

    禁止使用QQ及QQGame

    禁止使用QQ及QQGame,禁止使用QQ及QQGame禁止使用QQ及QQGame

    com.qqgame.deepin_5.24deepin0_i386.zip

    标题“com.qqgame.deepin_5.24deepin0_i386.zip”揭示了这是一个针对DEEPIN操作系统(一款基于Linux的发行版)的腾讯QQ游戏的压缩包。"5.24deepin0"可能是软件版本号,表明这是QQ游戏在DEEPIN系统上的一个特定更新。...

    手机QQGame斗地主安装程序

    方便手机QQ用户能够很快的玩斗地主,很爽的一个程序哦

    QQGame

    QQGame 是一个与游戏相关的项目或平台,但具体细节在提供的描述中并未明确。不过,我们可以根据标签“源码”和“工具”来推测QQGame可能涉及到的技术领域和相关知识点。 1. **游戏开发框架**:QQGame可能是一个游戏...

    QQGame_setup_web_11.EXE

    QQGame_setup_web_11.EXE

    e语言-高仿QQGAME登陆界面

    《易语言打造的高仿QQGAME登录界面解析》 易语言,一种以“易”为理念,面向普通用户的编程语言,以其简洁明了的语法设计,使得编程变得更加亲民。在本篇中,我们将深入探讨如何利用易语言来创建一个高仿QQGAME的...

    腾信-架构-QQGame后台架构

    腾信公司运营的QQGame是全球最大的休闲游戏平台之一,拥有超过3亿2千万的用户量和400万人的高峰同时在线人数。这个平台拥有比魔兽世界更出色的系统架构,它的成功不仅仅在于用户规模,还在于其强大的后台架构设计与...

    QQGame2012Beta8P1_setup_web

    好东西,大家来分享。最新qq东西,我们一起来聊聊天。

    高仿QQGAME登陆界面源码

    本案例中的"高仿QQGAME登陆界面源码"是一项基于易语言的编程实践,旨在创建一个与QQGAME登录界面相似的用户体验。易语言是一种中文编程语言,它的设计目标是使编程更加简单、直观和高效,尤其适合初学者和快速开发...

    后台架构以及开发介绍-架构师必读(腾讯QQGame案例分析)

    后台架构及开发介绍 1、整体结构框架 2、业务模块介绍 3、海量用户的运营 4、在现实中挣扎 非0即1不是我们的选择。

    QQlogin.rar_qqgame_自动 登陆

    QQ自动登陆器,VB编写,适用QQ2008,QQgame全部版本

    mif2png(QQGame 专用 mif 格式转 png 格式)

    QQGame是一款由腾讯开发的在线游戏平台,它拥有丰富的游戏资源和庞大的用户群体。在QQGame的游戏开发过程中,为了特定的平台需求,可能会使用到一些专有的文件格式,例如mif格式。mif文件通常包含了游戏中的图像资源...

    QQGame2009Beta5P2_setup_web

    QQGame2009Beta5P2_setup_web

    腾讯大讲堂44-QQGame后台开发介绍

    腾讯大讲堂44-QQGame后台开发介绍.ppt!

    QQGame后台架构及开发介绍

    QQGame后台架构是一个复杂而高效的系统,支撑着全球最大的休闲游戏平台,拥有超过3亿2千万用户,并且能同时容纳400万人在线,这样的规模甚至超过了著名的大型多人在线角色扮演游戏《魔兽世界》。这个系统因其出色的...

    QQGame对对碰辅助程序Delphi原代码

    1:能运行于Win98,WinMe,Win2000,WinXP和Win2003. 对游戏本身不会造成任何停顿.辅助用户,并有手工辅助 和自动挂机功能. 2:程序采取"系统热键"功能,"F10"显示和隐藏软件窗口. "Home"为开启自动挂机功能,"End"为...

    QQGame.exe

    QQ的材质包和补丁

    腾讯QQGame的PKG图片资源包文件解包源程序.rar

    说明:在VB下运行会出现“DLL 的调用约定错误(错误 49)”,但编译后运行EXE则正常。...  VB的Open语句打开文件,第1个字节位于1,而WinHex等十六进制编辑器第1个字节位于0  Private Sub MakeDirectory(strMainDir ...

Global site tag (gtag.js) - Google Analytics