手机游戏开发langren不会怎么办?

2013年3月 总版技术专家分月排行榜第二
2014年2月 Java大版内专家分月排行榜第一2013年8月 Java大版内专家分月排行榜第一2013年5月 Java大版内专家分月排行榜第一2013年4月 Java大版内专家分月排行榜第一2013年3月 Java大版内专家分月排行榜第一2013年2月 Java大版内专家分月排行榜第一
本帖子已过去太久远了,不再提供回复功能。探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法
相信这样一个问题,大家都不会陌生,
&有什么的方法可以使的程序APK不用安装,而能够直接启动&。
发现最后的结局都是不能实现这个美好的愿望,而腾讯Android手机游戏平台却又能实现这个功能,下载的连连看,五子棋都没有安装过程,但是都能直接运行,这其中到底有什么&玄机&呢,也有热心童鞋问过我这个问题,本文就为大家来揭开这个谜团。
我实现了一个小小的Demo,麻雀虽小五脏俱全,为了突出原理,我就尽量简化了程序,通过这个实例来让大家明白后台的工作原理。
下载demo的apk程序,其中包括了两个apk,分别是A和B
这两个APK可分别安装和运行,A程序界面只显示一个Button,B程序界面会动态显示当前的时间
下面的三幅图片分别为直接启动运行A程序(安装TestA.apk),直接启动运行B程序(安装TestB.apk)和由A程序动态启动B程序(安装TestA.apk,TestB.apk不用安装,而是放在/mnt/sdcard/目录中,即SD卡上)的截图,细心的同学可以停下来观察一下他们之间的不同
后两幅图片的不同,也即Title的不同,则解释出了我们将要分析的后台实现原理的机制
最能讲明白道理的莫过于了,下面我们就来分析一下A和B的实现机制,首先来分析TestA.apk的主要代码实现:
&&&& @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
&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);
代码解析:这就是OnCreate函数要做的事情,装载view界面,绑定button事件,大家都熟悉了,还有就是设置程序B的放置路径,因为我程序中代码是从/mnt/sdcard/TestB.apk中动态加载,这也就是为什么要让大家把TestB.apk放在SD卡上面的原因了。关键的函数就是最后一个了LoadAPK,它来实现动态加载B程序。
&&& 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].
&&&&&&&&&&&&&&& 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 });
&&&&&&&&&&& }
&&&&&&&&&&&
&&&&&&& } catch (Exception ex) {
&&&&&&&&&&& ex.printStackTrace();
&public void LoadAPK(Bundle paramBundle, String dexpath, String dexoutputpath) {
&&ClassLoader localClassLoader = ClassLoader.getSystemClassLoader();
&&DexClassLoader localDexClassLoader = new DexClassLoader(dexpath,
&&&&dexoutputpath, null, localClassLoader);
&&&PackageInfo plocalObject = getPackageManager()
&&&&&.getPackageArchiveInfo(dexpath, 1);
&&&if ((plocalObject.activities != null)
&&&&&&& (plocalObject.activities.length & 0)) {
&&&&String activityname = plocalObject.activities[0].
&&&&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 });
&&} 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程序的主代码:
&public class TestBActivity extends Activity {
&&& private static final String TAG = &TestBActivity&;
&&& private Activity otherA
&&& @Override
&&& public void onCreate(Bundle savedInstanceState) {
&&&&&&& boolean b =
&&&&&&& 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 = paramA
public class TestBActivity extends Activity {
&private static final String TAG = &TestBActivity&;
&private Activity otherA
&@Override
&public void onCreate(Bundle savedInstanceState) {
&&boolean b =
&&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 = paramA
代码解析:看完程序B的实现机制,大家是不是有种恍然大悟的感觉,这根本就是&偷梁换柱&嘛,是滴,程序B动态借用了程序A的上下文执行环境,这也就是上面后两幅图的差异,最后一幅图运行的是B的程序,但是title表示的却是A的信息,而没有重新初始化自己的,实际上这也是不可能的,所以有些童鞋虽然通过java的反射机制,正确呼叫了被调程序的onCreate函数,但是期望的结果还是没有出现,原因就是这个上下文环境没有正确建立起来,但是若通过startActivity的方式来启动APK的话,android系统会替你建立正确的执行时环境,所以就没问题。至于那个TBSurfaceView,那就是自定义的一个view画面,动态画当前的时间
&public class TBSurfaceView extends SurfaceView implements Callback, Runnable {
&&& private SurfaceH
&&& private T
&&& private C
&&& private P
&&& 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) {
public class TBSurfaceView extends SurfaceView implements Callback, Runnable {
&private SurfaceH
&private T
&private C
&private P
&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() {
&&&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();
&&&&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:
摘自 润物无声做手机棋牌游戏开发你不得不知道的那些事
如今人们的生活越发的便捷,无论是吃饭还是坐车一个手机APP就能搞定。工作结束后,大家总是下意识的拿出手机刷一刷,玩一玩,娱乐休闲也就成为了很理所当然的事情。但在众多的手机游戏中,大家似乎更钟情于棋牌游戏,或许是它的规则玩法家喻户晓,亦或许是其参与度高,但不管是什么原因,我们都无法否认棋牌游戏的那种独特的魅力永远都吸引着我们。棋牌游戏更加丰富了人们的娱乐生活,正是这样的需求催生出了棋牌游戏开发市场。
当然,在如此明朗的发展前景下,也引来了大量开发商来争抢市场。那么作为一名投资商,如何才能在棋牌游戏市场上淘到金呢?扬速科技就来为大家说一说关于手机棋牌游戏开发的那些事。
首先,调查好市场,抓住棋牌游戏平台盈利的几个关键点。在此基础上,不要落入运营陷阱。如下:
1、游戏门槛设定过高
在棋牌运营中,玩家就是运营商的命脉,一旦我们放弃了玩家肯定无法生存。然后,造成这种状况大多数的原因都是运营商对盈利过于急切。很多运营商在游戏运营一开始就有设定一个很高的门槛,各种收费道具设置,这样不仅无法获得快速盈利,而且容易造成玩家流失。对于游戏盈利收费,要循序渐进以游戏用户为先,好的服务才是盈利的基石。
2、贪小便宜,得不偿失。
专业正规的棋牌游戏开发商提供产品开发价格一般偏高,部分运营商就被价格低廉的小公司所诱惑。一般的小众棋牌开发公司开发团队实力薄弱,直接拿别人的开发源码进行修改,无自主的开发能力。这造成在棋牌游戏的运营过程中,系统不稳定经常掉线,bug多让维护难度大大增加,造成玩家流失,运营费用大增,种种造成最后入不敷出导致运营商失败。
3、盲目冲动,无法坚持到底。
如果你像个无头苍蝇在棋牌运营里横冲直撞,没有做好市场定位,没有选择合适的游戏,没有认真做推广运营工作,那你注定会失败。在棋牌运营商中,绝大部分人总是盲目冲动,无法坚持到底。网络棋牌游戏火热,很多运营商只看到别人的盈利,而没有看到别人的努力。
综上所述,我们大致可以把成功者的原因总结为:不贪图小利选择正规开发商,以用户为上不急于盈利,坚持到底善于学习,再加合理的运营策略,以及行业判断力。
接下来,我们在跟大家聊聊运营这一块。
什么是棋牌游戏运营呢,棋牌游戏运营即是将一款棋牌游戏平台推入市场,运营商通过一系列网络营销及地面宣传的不同营销手法,使游戏玩家从认识、了解并最终形成习惯,更大的粘住大批量玩家在游戏平台进行娱乐,并通过一系列的营销手段不断提高在线人数,刺激玩家冲值消费等目的,从而为运营商创造价值的这一过程。
它要求运营人员必须具备几个条件:
1.熟悉运营的产品,对产品有深入的了解
2.熟悉网络棋牌游戏市场,擅于分析玩家心理
3.重视数据分析
4.思维活跃,热爱棋牌游戏行业。
一般大多数人所理解的运营,主要集中于市场策划部分,事实上,运营一款棋牌游戏包括十大要素:
一、软、硬件的准备:
硬件指游戏运营服务器、带宽、域名、相关的系统软件等。这类硬件较为容易准备,找相关的idc资源租赁即可以马上解决上述问题。
软件指棋牌游戏的服务器端软件及棋牌游戏客户端等。在这里我们简称为“游戏平台”,对于棋牌游戏平台的选择,因为这在棋牌游戏运营中是至关重要的一个环节,因为棋牌游戏平台是创造价值的最关健所在,选择不慎,不光是平台的费用,还会连同后期的推广费用与自己的心力一起付之东流。
做棋牌游戏这一块其实并不难,难的是商家不被眼前利益所吸引,如果想要为长久的利益发展,棋牌游戏开发商的游戏产品质量不仅要过硬,还得要有自己的态度。当然,以上种种的方法都要建立在一个稳定优秀的棋牌平台上,并且找到一家优秀的棋牌游戏开发公司。扬速科技有限公司凭借自己多年的开发经验,成熟的开发技术,研制出上百款棋牌游戏。凭借自身丰富的资源优势,坚持自主创新,打造最具有核心竞争力的棋牌游戏,值得大家信赖!
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点}

我要回帖

更多关于 手机游戏开发公司 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信