cocos2dx中android下动态更新.so文件
作者:HU
转载请注明,原文链接:http://www.cnblogs.com/xioapingguo/p/4037595.html
因为没用lua脚本写游戏,所以每次发布出去后,发现在bug,需要更新APK重新安装,严重影响体验,增加玩家流失率。如果使用直接更新.so文件的话,就可以解决这个问题。
1、下载.so文件,使用游戏本身的资源更新方法,下载下来,到文件的file/res目录
.so文件zip压缩一下会小很多,解压方法参考http://www.cnblogs.com/xioapingguo/p/4037323.html
2、把.so文件拷贝到 存放目录(根据自己喜好,不拷贝也可以),这里我将存到file/libs/目录中,把原来目录file/res中的libgame.so删除
文件拷贝方法:
public static void copyFile(File sourceFile,File targetFile)throws IOException{ if(!targetFile.exists()){ targetFile.getParentFile().mkdirs(); targetFile.createNewFile(); } FileChannel fc1 = null; FileChannel fc2 = null; try { fc1 = new FileInputStream(sourceFile).getChannel(); fc2 = new FileOutputStream(targetFile).getChannel(); fc2.transferFrom(fc1, 0L, fc1.size()); } finally { if(fc1!=null) { fc1.close(); } if(fc2!=null) { fc2.close(); } } }
3、判断是否要重启游戏(.so文件更新后要重启游戏,因为下载资源是在之前的.so文件里执行的,如果想要不重启游戏,必须在java中做资源更新)
因为在小米系统中ALARM_SERVICE是不准的,所以重启有可能是不会成功,只要提示用户自己手动重启了,目前没有解决办法。
public static boolean isNeedRestratApplication() throws IOException { String str = sContext.getFilesDir()+"/libs/libgame.so"; File updateFile = new File(sContext.getFilesDir()+"/res/libgame.so"); Log.d(TAG, "str="+str); if(updateFile.exists())//检查是否有更新 { Log.d(TAG,"copyFile"); copyFile(updateFile,new File(str));//拷贝文件 updateFile.delete();//删除原来的文件 } else { Log.d(TAG,"return"); return false; }
//开始重启游戏 str = Cocos2dxHelper.getCocos2dxPackageName(); Intent localIntent = new Intent("android.intent.action.MAIN"); localIntent.addCategory("android.intent.category.LAUNCHER"); localIntent.setComponent(new ComponentName(str,"org.cocos2dx.cpp.AppActivity")); localIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Context localContext = Cocos2dxActivity.getContext(); PendingIntent localPendingIntent = PendingIntent.getActivity(localContext, (int)System.currentTimeMillis(), localIntent, PendingIntent.FLAG_CANCEL_CURRENT); AlarmManager localAlarmManager = (AlarmManager)localContext.getSystemService(android.content.Context.ALARM_SERVICE); localAlarmManager.set(AlarmManager.RTC, 1000L+System.currentTimeMillis(), localPendingIntent);//延时1秒钟 Process.sendSignal(Process.myPid(),Process.SIGNAL_QUIT); return true; }
4、修改Cocos2dxActivity.java下,让游戏使用下载的.so文件运行游戏。(cocos2d-x 3.2下,其它版本按具体情况修改)
protected void onLoadNativeLibraries() { try { ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA); Bundle bundle = ai.metaData; String libName = bundle.getString("android.app.lib_name"); //System.loadLibrary(libName); File file = new File(getFilesDir().getAbsolutePath()+ "/libs/libgame.so");//下载到的.so文件,如果不存在,则使用原来安装时的 Log.d(TAG, "onLoadNativeLibraries =" + getFilesDir().getAbsolutePath()+ "libs/libgame.so"+" isexists="+file.exists()); if (file.exists()) { try { System.load(file.getAbsolutePath()); } catch(UnsatisfiedLinkError err) { Log.d(TAG, "onLoadNativeLibraries = fail"); } } else { System.loadLibrary(libName); } } catch (Exception e) { e.printStackTrace(); } }