android APK知识
16lz
2021-01-23
最近在研究Android动态加载APK技术,偶有小得,共享一下,欢迎交流。
首先是Android 动态加载已安装的APK
截图:
被调用工程TestB:
其工程已添加了字符串、颜色和图片资源,这里不写了,读者可自行添加。
[java] view plain copy
- publicclassTestBActivityextendsActivity{
- /**Calledwhentheactivityisfirstcreated.*/
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- Buttonbutton=(Button)findViewById(R.id.button1);
- button.setOnClickListener(newOnClickListener(){
- @Override
- publicvoidonClick(Viewv){
- //TODOAuto-generatedmethodstub
- Toast.makeText(TestBActivity.this,"thisistestB",Toast.LENGTH_SHORT).show();
- }
- });
- }
- }
接着把TestB打包为TestB.apk,放到sdcard的根目录。
首先应该是安装apk文件:
[java] view plain copy
- protectedvoidInstallAPK(Stringapkname){
- //TODOAuto-generatedmethodstub
- //代码安装
- StringfileName=Environment.getExternalStorageDirectory()+"/"+apkname;
- Intentintent=newIntent(Intent.ACTION_VIEW);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- //intent.setDataAndType(Uri.parse("file://"+fileName),"application/vnd.android.package-archive");
- intent.setDataAndType(Uri.fromFile(newFile(fileName)),"application/vnd.android.package-archive");
- TestAActivity.this.startActivityForResult(intent,1);
但是安装之前是不是要先检测一下TestB.apk是否已安装呢:
[java] view plain copy
- protectedbooleancheckInstall(Stringpak){
- //TODOAuto-generatedmethodstub
- booleaninstall=false;
- PackageManagerpm=getPackageManager();
- try{
- PackageInfoinfo=pm.getPackageInfo(pak,1);
- if(info!=null&&info.activities.length>0){
- install=true;
- }
- }catch(NameNotFoundExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }
- returninstall;
- }
如果未安装,便调用InstallAPK(String apkname)安装,如果已安装便可代码获取其资源:
[java] view plain copy
- privatevoidgetRes(Stringpak){
- if(checkInstall(pak)){
- try{
- ContextctxTestB=getTestContext(pak);
- Resourcesres=ctxTestB.getResources();
- //获取字符串string
- Stringhello=res.getString(getId("string","hello",pak));
- ((TextView)findViewById(R.id.testb_string)).setText(hello);
- //获取图片Drawable
- Drawabledrawable=res.getDrawable(getId("drawable","testb",pak));
- ((ImageView)findViewById(R.id.testb_drawable)).setImageDrawable(drawable);
- //获取颜色值
- intcolor=res.getColor(getId("color","white",pak));
- ((TextView)findViewById(R.id.testb_color)).setBackgroundColor(color);
- //获取布局文件
- Viewview=getView(ctxTestB,getId("layout","main",pak));
- LinearLayoutlayout=(LinearLayout)findViewById(R.id.testb_layout);
- layout.addView(view);
- }catch(NameNotFoundExceptione){
- e.printStackTrace();
- }}
- }
- //获取资源对应的编号
- privateintgetId(Stringname,Stringtype,Stringpak){
- returntestb.getIdentifier(name,type,pak);
- }
- //获取视图
- publicViewgetView(Contextctx,intid){
- return((LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(id,null);
- }
- //获取TestB的Context
- privateContextgetTestContext(Stringpak)throwsNameNotFoundException{
- returncreatePackageContext(pak,Context.CONTEXT_IGNORE_SECURITY|Context.CONTEXT_INCLUDE_CODE);
- }
接下来再来看看怎么使用Intent组件启动被调用工程:
[java] view plain copy
- protectedvoidstartAPK(Stringpak){
- //TODOAuto-generatedmethodstub
- //代码启动
- try{
- //pak=PACKAGE_TEST_B+".TestBActivity"
- ContextctxTestB=getTestContext(PACKAGE_TEST_B);
- Classcls=ctxTestB.getClassLoader().loadClass(pak);
- TestAActivity.this.startActivity(newIntent(ctxTestB,cls));
- }catch(ClassNotFoundExceptione){
- e.printStackTrace();
- }catch(NameNotFoundExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }
- }
以下为扩展内容:
比如加上网络下载apk文件功能,然后再安装,这里使用的是URL通信协议,用HttpURLConnection类,面向的是应用层:
[java] view plain copy
- protectedFiledownLoadFile(StringhttpUrl){
- //TODOAuto-generatedmethodstub
- Stringfilename="down_TestB.apk";
- Filefile=newFile(Environment.getExternalStorageDirectory()+"/"+filename);
- try{
- URLurl=newURL(httpUrl);
- try{
- HttpURLConnectionconn=(HttpURLConnection)url
- .openConnection();
- InputStreamis=conn.getInputStream();
- FileOutputStreamfos=newFileOutputStream(file);
- byte[]buf=newbyte[256];
- conn.connect();
- intcount=0;
- if(conn.getResponseCode()==200){
- while((count=is.read(buf))>0){
- fos.write(buf,0,count);
- }
- }
- conn.disconnect();
- fos.close();
- is.close();
- }catch(IOExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }
- }catch(MalformedURLExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }
- returnfile;
- }
更多相关文章
- Android实践 -- Android文件储存系统 应用篇
- Android添加资源文件编译,R文件未重新生成解决办法
- 1.4.2 Android Studio工程目录结构分析
- 转 Android:文件下载和写入SD卡学习小结
- Android 之如何添加 android private libraries 中的包的源代码
- android下快速检索出媒体文件所在文件夹
- Android 7.0 之后抓包 unknown 和证书无效的解决方案(无需改代码)
- Android RIL代码详细分析