android动态加载jar

最近做的android项目出现被破解问题,我从网上搜索到可以用动态加载jar的办法,将需要隐藏的代码打成资源jar,让后在使用时动态加载jar。但是在实际操作时出现问题,因为打成jar的代码需要调用工程中其他的class或是jar,这样动态加载时会报noClassFound异常。纠结了很久发现是classloader的问题,因为动态加载jar所需的DexClassLoader与项目Application的classLoader不是同一个(可参考http://www.cnblogs.com/xitang/p/3534777.html),如果可以用DexClassLoader替换掉Application的classLoader就可以了。

jar的加载:(jar放在assert中)

<pre name="code" class="java">DexClassLoader dexClassLoader= null;
		 ClassLoader localClassLoader = this.getClassLoader();
	      try {  
	    	  InputStream in = getResources().getAssets().open("encode.data");
	    	  File dexInternalStoragePath = new File(getDir("pay", Context.MODE_PRIVATE), "dex.jar");
	    		    if (!dexInternalStoragePath.exists()) {
	    		      try {
	    		        dexInternalStoragePath.createNewFile();
	    		      } catch (IOException e) {
	    		        // TODO Auto-generated catch block
	    		        e.printStackTrace();
	    		      }
	    		    }
	    	FileOutputStream out = new FileOutputStream(dexInternalStoragePath);
	    	  //CopyFile.copyFile(inputStream, fileOutputStream);
	    	  byte[] buffer = new byte[1024];  
	          int length;  
	          in.read();
	          while ((length = in.read(buffer)) > 0) {  
	        	  out.write(buffer, 0, length);
	        	  in.read();
	          }  
	          out.flush();  
	          in.close(); 
	          out.close();
	          //String outpath = getApplicationInfo().dataDir;
	          final File optimizedDexOutputPath = getDir("temp",Context.MODE_PRIVATE);
	          String nativeDir = this.getApplicationInfo().nativeLibraryDir;
	          dexClassLoader = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
	                  optimizedDexOutputPath.getAbsolutePath(), null , localClassLoader);  
	          replaceClassLoader(dexClassLoader);
	      } catch (Exception e) {  
	          e.printStackTrace();  
	      }


 替换classLoder 

private void replaceClassLoader(ClassLoader classLoader)
	{
		try {
			Field mMainThread = this.getBaseContext().getClass().getDeclaredField("mMainThread");
			mMainThread.setAccessible(true);
			Object mainThread = mMainThread.get(this.getBaseContext());
			Class threadClass = mainThread.getClass();
			Field mPackages = threadClass.getDeclaredField("mPackages");
			mPackages.setAccessible(true);
			WeakReference<?> ref;
			Map< String , ?> map =(Map< String , ? >) mPackages.get(mainThread ) ;
			ref = (WeakReference<? >) map.get(this.getPackageName());
			Object apk = ref.get();
			Class apkClass = apk.getClass();
			Field mClassLoader = apkClass.getDeclaredField("mClassLoader");
			mClassLoader.setAccessible(true);
			mClassLoader.set(apk, classLoader);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

但是这个还是有问题,就是如果jar中有调用本地代码,还是会报错,即使我修改了 DexClassLoader第三个参数,依然不行,这个问题我还没有想到好的办法,若哪位知道求告知

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值