插件化开发

插件包括使用zip、jar、dex、apk(未安装、安装)

这里写图片描述

public class MainActivity extends Activity {
  private ImageView imageSource;
  private ImageView imageCloud;
  private final static String SRC_TAG = "srcTag";
  private final static String CLOUD_TAG = "cloud";
  @Override
  protected void onCreate(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  initView();

}

private void initView() {
  imageSource = (ImageView)findViewById(R.id.imageSource);
  imageCloud = (ImageView)findViewById(R.id.imageCloud);
  imageSource.setTag(SRC_TAG);
  imageCloud.setTag(CLOUD_TAG);
  imageSource.setOnClickListener(this);
  imageCloud.setOnClickListener(this);
}

@Override
public void onClick(View v) {
  if(v.getTag().equals(SRC_TAG)){
     //点到了本地动画
     handleAnim(v);
  }else if(v.getTag().equals(CLOUD_TAG)){
     //插件动画
     String fileName = CLOUD_TAG+".apk";
     //this.getCacheDir()获取/data/data//cache目录
     String filePath = this.getCacheDir()+File.separator+fileName;
     String packageName = "com.dn."+CLOUD_TAG;
     File apkFile = new File(filePath);
     if(apkFile.exists()){
       //直接加载插件
       Drawable backGround = v.getBackground();
       if(backGround instanceof AnimationDrawable){
          handleAnim(v);
        }else{
          //第一次加载插件
          try{
             AssetManager assetManager =        PluginResources.getPluginAssetManager(apkFile);
          //插件的resource对象
             Resources resources = PluginResources.getPluginResources(getResource(),assetManager);
             DexClassLoader classLoader = new DexClassLoader(apkFile.getAbsolutePath(),this.getDir(fileName,Context.MODE_PRIVATE).getAbsolutePath(),null,getClassLoader());
Class<?> loadClass =              classLoader.loadClass(packageName+".R$anim"); 
Field[] declaredFields = loadClass.getDeclaredFields();

for(Field field : declaredFields){
   if(field.getName().equals(CLOUD_TAG)){
      //云的animId
      int animId = field.getInt(R.anim.class);
      //插件的动画
      Drawable drawable = resources.getDrawable(animId);
      ((ImageView)v).setBackgroundDrawable(drawable);
      handleAnim(v);
   }

}

          }catch(Exception e){
             e.printStackTrace();
          }


        }
     }else{
       //下载插件
       InputStream is = null;
       FileOutputStream os = null;
       try{
         is = this.getAssets().open(fileName);
         os = new FileOutputStream(filePath);
         int len=0;
         byte[] buffer = new byte[1024];
         while((len=is.read(buffer))!=-1){
           os.write(buffer,0,len);
         }
         Toast.makeText(this,"下载完成",Toast.LENGTH_LONG).show();
       }catch(Exception e){
         e.printStackTrace();
       }finally {
         try{
            if(is!=null){
              is.close();
            }
            if(os!=null){
              os.close();
            }
          }catch(Exception e){
            e.printStackTrace();
          }

       }
     }
  }
}

private void handleAnim(View v) {
  AnimationDrawable drawable = (AnimationDrawable)v.getBackground();
  if(drawable!=null){
    if(drawable.isRunning()){
       drawable.stop();
    }else{
      drawable.stop();
      drawable.start();
    }
  }
}

}

插件化

自己定义加载资源的Resource类

public class PlguinResources extends Resources {

  public PlguinResources(AssetManager assets, DisplayMetrics metrics, Configuration config){
   super(assets, metrics,config);
  }

  //自己加载插件的apk来返回插件的Resources
  public static PluginResources getPluginResources(Resources res,AssetManager assets){
    PluginResources pluginResources = new PluginResources(assets,res.getDisplayMetrics(),res.getConfiguration());
   return pluginResources ;
  }

//自己定义assetsManager
public static AssetManager getPluginAssetManager(File apkFile) throws ClassNotFoundException{
   Class<?> forName =   Class.forName("android.content.res.AssetManager");
  Method[] declaredMethods = forName.getDeclaredMethods();
  for(Method method:declaredMethods){
     if(method.getName().equals("addAssetPath")){
     try{
     AssetManager assetManager = AssetManager.class.newInstance();
     method.invoke(assetManager,apkFile.getAbsolutePath());
     return assetManager;
   }catch(Exception e){
    e.printStackTrace();
   }
  }
 }
return null;
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值