美文网首页Android开发AndroidAndroid开发
Android动态加载-腾讯SDK定位。动态加载.so文件

Android动态加载-腾讯SDK定位。动态加载.so文件

作者: b496178cdc84 | 来源:发表于2016-09-29 09:26 被阅读1269次

    最近有个新需求,要求进行定位。但是项目本身用的是动态加载框架,在只更新插件的情况下,做到定位需求。先说说Android定位,由于自带的定位不稳定,我自己测试的时候返现在室内基本都是定位不到,再加上,谷歌服务基本都被大部分厂商砍掉。所以为了准确性和稳定性,暂时只能用第三方应用。
    BAT的三个地图SDK,百度和阿里的由于要在AndroidMainfest文件中注入一个定位服务,这就意味着要更新动态加载框架,所以这2个肯定是不能用的,所以选择了腾讯的,精简,size小,实现方便。最重要的是不需要再AndroidMainfest注入服务。但是文档中说要注入一个meta-data 用来写入ID,我的做法是直接改了他的jar包,然后写死id,这样就不需要在AndroidMainfest中注入了。
    OK,下一步就是导入腾讯SDK提供的.so文件,

    正常方法,在main下建立jniLibs,然后安装的时候,会把jniLibs里面的拷贝到data/app/packageName/libs下。然后运行时候就会根据CPU的类型,到这个目录去加载最匹配的.so文件。

    然而,我们是动态加载,并不能使用这种方法,因为我们插件打包的时候并不能指定在data/app/package/下保存.so文件。

    所以,一开始有个想法,动态加载.so文件,就是在运行时候,把.so放在assets里面,然后拷贝到data/app/context.getpackage/libs里面,然后加载so,然而尝试了一番,发现并不行,因为data/app/packageName/libs 这个目录只有可读权限。并不能写入。

    换方法,了解到,System.load 和 System.loadLibrary 可以动态加载.so,先是尝试了system.loadlibry, 这种不行因为这个方法,固定的加载目录是在data/app/packageName/libs,所以不能使用,于是使用system.load() 指定绝对路径,OK可以了。有一点需要注意的是,system.load方法只能加载在data/app/packageName/libs下的 或者 在私有目录(data/data/package/...)下的,所以,同样采用在assets中存放.so 运行中动态拷贝。
    上代码

    /** * 初始化location,主要做一些拷贝.so的操作 */
      public void initLoacation() {
        LogUtils.d(Build.CPU_ABI);
        File soFile = null;  
      if (DeviceInfo.getDeviceCpu().equals("armeabi-v7a")) {   
         soFile = new File(mContext.getFilesDir(), "libtencentloc-v7a.so");    
    }else if (DeviceInfo.getDeviceCpu().equals("armeabi")) {   
         soFile = new File(mContext.getFilesDir(), "libtencentloc-v7a.so"); 
       } else if (DeviceInfo.getDeviceCpu().equals("x86")) {   
        soFile = new File(mContext.getFilesDir(), "libtencentloc-x86.so"); 
       }  if (soFile.exists()) {  
          System.load(soFile.getAbsolutePath()); 
           startLocation();    
    } else { 
           copySoFileToLocal(soFile);    }}
    

    上边就是先判断CPU的架构,然后不同的架构,拷贝不同的.so文件,.So文件我是放在assets目录下

    /** * 拷贝.so文件 * * 
    @param soFile
     */
    private void copySoFileToLocal(final File soFile) {   
     new Thread(new Runnable() { 
           @Override        
         public void run() {           
                 try {                
     InputStream inputStream = mContext.getResources().getAssets().open(soFile.getName());                           
     FileOutputStream fos = mContext.openFileOutput(soFile.getName(), Context.MODE_PRIVATE);                
     IOUtils.in2out(inputStream, fos);               
     System.load(soFile.getAbsolutePath());               
     LogUtils.d("had load " + soFile.getAbsolutePath());                
    KyxSDKGlobal.runOnMainThread(new Runnable() {                    
    @Override                   
     public void run() {   
              startLocation(); }
      }); } catch (IOException e) {  
                  e.printStackTrace(); 
                   LogUtils.d("error");  
              } }}).start();}
    

    OK,这样就可以把.so加载成功了。然后就可以继续执行腾讯SDK的相关方法

    相关文章

      网友评论

        本文标题:Android动态加载-腾讯SDK定位。动态加载.so文件

        本文链接:https://www.haomeiwen.com/subject/tnxhyttx.html