android 动态加载.so

转载请注明,原文链接: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();
        }
    }
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值