`
king_tt
  • 浏览: 2290701 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Andrdoid中实现静态的默认安装和卸载应用

 
阅读更多

最近好长时间都没有写blog了,主要是因为最近工作上的事以及下载Android源码的事耽误的(下载源码这件事会在后续的blog中写道,这个真的很有意义呀~~),那么今天来写点什么呢?主要的灵感来自于早上看新闻看到一篇文章说有一款应用在后台中卸载用户手机中的所有浏览器的app,不会被用户察觉,但是最后百度浏览器还是用反侦察技术找到这个邪恶的应用然后将其告上法庭了。那么我们就来看看怎么能够实现应用的静态安装和卸载呢?就是不让用户知道,下面就来一步一步的介绍一下实现步骤:


一、访问隐藏的API方式进行静态的默认安装和卸载

1.系统安装程序

android自带了一个安装程序---/system/app/PackageInstaller.apk.大多数情况下,我们手机上安装应用都是通过这个apk来安装的。代码使用也非常简单:

/* 安装apk */
public static void installApk(Context context, String fileName) {
	Intent intent = new Intent();
	intent.setAction(Intent.ACTION_VIEW);
	intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
	intent.setDataAndType(Uri.parse("file://" + fileName),"application/vnd.android.package-archive");
	context.startActivity(intent);
}

/* 卸载apk */
public static void uninstallApk(Context context, String packageName) {
	Uri uri = Uri.parse("package:" + packageName);
	Intent intent = new Intent(Intent.ACTION_DELETE, uri);
	context.startActivity(intent);
}
通过发一个Intent,把应用所在的路径封装整uri.之后默认启动了PackageInstaller.apk来安装程序了。
但是此种情况下,仅仅是个demo而已,很难达到开发者的需求。如:
1).界面不好

2).被用户知晓

3).什么时候安装完了,卸载完了呢?

当然这里关于第三点的话,为了达到自己的需求,相信很多人都会接着来监听系统安装卸载的广播,继续接下来的代码逻辑。


监听系统发出的安装广播
在安装和卸载完后,android系统会发一个广播
android.intent.action.PACKAGE_ADDED(安装)
android.intent.action.PACKAGE_REMOVED(卸载)

咱们就监听这广播,来做响应的逻辑处理。实现代码:

public class MonitorSysReceiver extends BroadcastReceiver{
      
    @Override  
    public void onReceive(Context context, Intent intent){
        //接收安装广播 
        if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {   
            //TODO    
        }   
        //接收卸载广播  
        if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) {   
            //TODO
        }
    }
}


AndroidManifest.xml文件中的配置:
  <receiver android:name=".MonitorSysReceiver">   
            <intent-filter>  
             <action android:name="android.intent.action.PACKAGE_ADDED" />  
             <action android:name="android.intent.action.PACKAGE_REMOVED" />  
            </intent-filter>  
  </receiver>


到此,确实安装卸载的整体流程都知道了,但是这个效果肯定是无法达到项目的需求。
一般这种应用商店类(豌豆荚)的项目,肯定是会要自定义提示框效果的安装卸载功能,而不是调用系统的安装程序。
那咱就要想法子实现静默安装、卸载咯。

下面这种调用系统隐藏api接口来实现静默安装卸载,是比较大众靠谱的,实现自定义的提示界面。

(关于这个调用系统隐藏的api接口,我们在之前讲到如何获取手机电量的一篇文章中介绍过了

http://blog.csdn.net/jiangwei0910410003/article/details/25994337)


2.系统隐藏的api

隐藏api,顾名思义,普通情况下肯定是调用不到的。翻翻源码\frameworks\base\core\java\android\content\pm目录下PackageManager.java,应该发现
在注释行里有加上@hide声明。调用的安装下载接口如下:

安装接口:

public abstract void installPackage(Uri packageURI,IPackageInstallObserver observer, int flags,String installerPackageName);
卸载接口:
public abstract void deletePackage(String packageName,IPackageDeleteObserver observer, int flags);


并且都是抽象方法,需要咱们实现。
看参数里IPackageInstallObserver observer一个aidl回调通知接口,当前目录中找到这接口:
package android.content.pm;

/**
 * API for installation callbacks from the Package Manager.
 * @hide
 */
oneway interface IPackageInstallObserver {
    void packageInstalled(in String packageName, int returnCode);
}

好吧,这里有现成的干货,咱拿过来直接用呗(当然如果没有源码的那就算了,那能实现的只是demo)。具体步骤:
从源码中拷贝要使用的aidl回调接口:IPackageInstallObserver.aidl、IPackageDeleteObserver.aidl当然完全可以拷贝整个pm目录,这样就不会报错了。
作者项目里面用到了pm,所以把PackageManager.java以及涉及到的一些文件也拷贝过来了,不然eclipse报找不到PackageManager对象。结构如下:



注:此处的包名android.content.pm一定要和源码目录结构一致,不然源码里编译会提示找不到aidl接口。一切朝源码编译看齐
此处有2种方式实现:
1.直接只取IPackageDeleteObserver.aidl和IPackagerInstallObserver.aidl、IPackageMoveObserver.aidl等要使用的接口,然后通过bindService来和系统连接服务,然后直接调用接口即可(这种没有方式作者没试过,不过原理上来说应该是可行的,除非系统没有这个Service实现这个接口。有需求的可以深究下)
2.作者此处的方法是直接拷贝了源码PackageManager.java等文件过来,不过靠过来之后eclipse会提示一些接口错误,但这里作者把上面那几个.java文件都放空了,因为用不到,只是为了编译过才拷贝了那么多文件。最简单的就是直接拷贝4个文件即可:
PackageManager.java
IPackageDeleteObserver.aidl
IPackagerInstallObserver.aidl
IPackageMoveObserver.aidl

然后把PackageManager.java中报的异常的接口都注释掉即可
实现回调接口,代码如下:

安装的回调接口:

/*静默安装回调*/
class MyPakcageInstallObserver extends IPackageInstallObserver.Stub{
		
	@Override
	public void packageInstalled(String packageName, int returnCode) {
		if (returnCode == 1) {
			Log.e("DEMO","安装成功");
			new ToastThread(InstallActivity.this,"安装成功").start();
		}else{
			Log.e("DEMO","安装失败,返回码是:"+returnCode);
			new ToastThread(InstallActivity.this,"安装失败,返回码是:"+returnCode).start();
		}
	}
}


安装的方法:
String fileName = Environment.getExternalStorageDirectory() + File.separator + "baidu"+File.separator +"UC.apk";
Uri uri = Uri.fromFile(new File(fileName));
int installFlags = 0;
PackageManager pm = getPackageManager();
try {
PackageInfo pi = pm.getPackageInfo("com.UCMobile",PackageManager.GET_UNINSTALLED_PACKAGES);
if(pi != null) {
installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
}
} catch (NameNotFoundException e) {
}
MyPakcageInstallObserver observer = new MyPakcageInstallObserver();
pm.installPackage(uri, observer, installFlags, "com.UCMobile");
从代码中可以看到我们想安装的是从SD卡中的baidu文件夹中的UC.apk(所以在测试程序的时候需要将UC.apk拷贝到SD卡中的baidu文件夹中,或者你可以自定义一个文件的存放目录)


卸载原理是一样的

卸载的回调接口:

/* 静默卸载回调 */
class MyPackageDeleteObserver extends IPackageDeleteObserver.Stub {

	@Override
	public void packageDeleted(String packageName, int returnCode) {
		if (returnCode == 1) {
			Log.e("DEMO","卸载成功...");
			new ToastThread(InstallActivity.this,"卸载成功...").start();
		}else{
			Log.e("DEMO","卸载失败...返回码:"+returnCode);
			new ToastThread(InstallActivity.this,"卸载失败...返回码:"+returnCode).start();
		}
	}
}


卸载的功能:

PackageManager pm = InstallActivity.this.getPackageManager();
IPackageDeleteObserver observer = new MyPackageDeleteObserver();
pm.deletePackage("com.UCMobile", observer, 0);
这里我们一定要传一个包名。


自此,静默安装卸载代码实现。最后在AndroidManifast.xml中要注册权限和添加为系统用户组

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.autoinstallpackage.demo"   
    android:versionCode="1"
    android:versionName="1.0.19"
    android:sharedUserId="android.uid.system">
    
    <uses-sdk android:minSdkVersion="4"/>
 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
	<uses-permission android:name="android.permission.INTERNET" />
	<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
	<uses-permission android:name="android.permission.DELETE_PACKAGES" />
	<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
	<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> 
    ...

</manifest>


这里要注意的地方有两个:第一个必须要添加:

android:sharedUserId="android.uid.system"

这个是将其应用注册成系统用户组中


还要添加安装和卸载的权限:

<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />


这时候上面的工作都做完之后,那么我们就来用Eclipse运行一下吧:


好吧,貌似不是那么的顺利,出现一个安装错误,其实这个信息去百度一下之后会找到很多的相关资料,因为这个问题有很多人遇到过,所以解决的方法也是很多的,就是需要将我们的应用签名成系统级的即可,那么我们该怎么办呢?


网上普遍的两种方法:

第一种是:得到platform.pem,platform.x509.pem,signapk.jar这三个文件进行签名:签名的命令很简单:

java -jar signapk.jar platform.x509.pem platform.pem 需要签名的apk 签名之后的apk

下图是我签名的操作:



第二种方法:很麻烦的,为什么说麻烦呢?因为需要下载源代码,然后将我们的应用拷贝到指定的目录即可:

1.如果你有系统源码,最简单的就是将eclipse里面的应用拷贝到系统里面,然后编译系统,会生成out/target/product/generic/system/app/abc.apk,这个应用就是经过系统签名了。具体方法如下:
将应用文件夹复制到源码目录:packages/experimental/project_name/里面,并且只保留src、res、libs、androidmanifest.xml这三个文件,里面新建一个Android.mk文件,内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := abc
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)

然后进行编译即可


其实我们在将第一种方法的时候有一个问题就是那三个签名的文件到哪里能搞到,这个吗?可以到网上去搜索的,但是本人在下载la下来然后进行签名,结果总是失败,于是,我就放弃了从网上去下载,那么还有什么方法可以得到呢?好吧,还得去下载Android源码,编译之后可以在指定的目录中找到这三个文件


但是还没有完,不管是第一种方法还是第二种方法,我在试验的过程中还是失败,原因是什么呢?因为我们如果用这三个文件进行签名或者把工程放到源码中进行编译的话,都必须要注意一点:就是签名的文件的系统版本必须和安装到设备的系统的版本一样说白一点:现在假如签名的那三个文件是从下载的编译之后的源码中得到的,那么这三个文件的版本就是这个Android源码的版本:比如是4.4版本的,那么我们用这三个文件进行签名之后的apk包只能安装到系统版本为4.4的机子上,同理如果我们将工程直接放到Android源码中进行编译的话,假如Android源码的系统版本是4.4,那么编译之后的apk也只能安装到系统版本为4.4的机子上。


所以我们从网上下载到的签名的三个文件进行签名之后总是失败,所以这种方式总是不靠谱的,因为我们从网上下载的签名文件肯定不知道他的版本号,但是我们可以将签名之后的包安装到每个版本的系统中进行尝试,所以最靠谱的方式还是我们下载源码然后得到这三个签名的文件即可,因为我们自己下载的源码肯定知道版本的。

这三个文件对应的目录是:

signapk.jar: 源码目录/out/host/linux-x86/framework/signapk.jar

platform.pk8和platform.x509.pem: 源码目录/build/target/product/security/platform.pk8&platform.x509.pem


当我们使用第一种方法的时候,我们需要用Eclipse中导出一个未签名的包,这个很简单了,这里就不介绍了~~


运行的结果:


因为手头上没有4.4系统的机子,又不想刷机,所以就用模拟器了。在这个过程中安装和卸载可能要一段时间,所以要等待一会,不要着急~~


那么我们就介绍了使用隐藏的api来进行默认的安装和卸载app,

Demo工程下载地址:

http://download.csdn.net/detail/jiangwei0910410003/7584423

导入工程之后,需要做的几步:

在SD卡中拷贝一个UC.apk到baidu文件夹(需要新建的)

导出未进行签名的包

下载签名的工具:

http://download.csdn.net/detail/jiangwei0910410003/7584441

按照上面的签名步骤进行操作

然后找到一个系统是4.4版本的测试机或者模拟器进行安装包(因为我的签名文件的版本是4.4)


二、通过命令进行静态的默认安装和卸载

下面我们再来看一下如何使用命令的方式来实现默认的安装和卸载app,我们知道可以使用命令:

adb install apk文件

adb uninstall 包名

进行安装和卸载操作。


我们在代码中可以使用Runtime类进行操作:

Runtime.getRuntime().exec("adb uninstall com.UCMobile");
或者ProcessBuilder:

new ProcessBuilder().command("adb","uninstall","com.UCMobile").start(); 

看到这两个类的区别在于,第一种是将命令一起写完,第二种是将命令用空格分隔,然后将其当做参数进行传递的,其实command方法的参数是一个String可变参数类型的


但是我们执行上面的代码发现总是执行失败,结果才发现,这些命令执行的目录不是在shell层的,但是手机中执行的命令必须要在shell层中的,所以会有问题的,但是我们可以使用pm命令,比如我们使用PC端的命令行进行安装文件:

>adb shell

>pm install apk文件

其实上面的两行命令和

>adb install apk文件

的效果一样

但是如果想在手机上执行安装文件只能执行命令:pm install apk文件

(可以把pm命令的作用想成是脱离shell层来执行命令的)


不多说了,下面就来看一下代码吧:

/* 
* m命令可以通过adb在shell中执行,同样,我们可以通过代码来执行 
*/  
public static String execCommand(String ...command)  {  
	Process process=null;  
	InputStream errIs=null;  
	InputStream inIs=null;  
	String result="";  

	try {  
		process=new ProcessBuilder().command(command).start();  
		ByteArrayOutputStream baos = new ByteArrayOutputStream();  
		int read = -1;  
		errIs=process.getErrorStream();           
		while((read=errIs.read())!=-1){  
			baos.write(read);  
		}  
		inIs=process.getInputStream();  
		while((read=inIs.read())!=-1){  
			baos.write(read);  
		}  
		result=new String(baos.toByteArray());  
		if(inIs!=null)  
			inIs.close();  
		if(errIs!=null)  
			errIs.close();  
		process.destroy();  
	} catch (IOException e) {  
		result = e.getMessage();  
	}  
	return result;  
}  

调用这个方法:

protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		final String path = Environment.getExternalStorageDirectory() + File.separator + "baidu"+File.separator + "360MobileSafe.apk";
		
		Button btn1 = (Button) findViewById(R.id.btn1);
		btn1.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				//安装apk,filePath为apk文件路径,如/mnt/sdcard/ApiDemos.apk
				String result = execCommand("pm","install","-f",path);
				Toast.makeText(MainActivity.this, "安装结果:"+result, Toast.LENGTH_LONG).show();
			}});
		
		Button btn2 = (Button) findViewById(R.id.btn2);
		btn2.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				//卸载apk,packageName为包名,如com.example.android.apis
				String result = execCommand("pm","uninstall", "com.qihoo360.mobilesafe");
				Toast.makeText(MainActivity.this, "卸载结果:"+result, Toast.LENGTH_LONG).show();
			}});
		
	}

在AndroidManifest.xml中的配置:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="com.xieyuan.mhfilemanager"  
    android:versionCode="1"  
    android:versionName="1.0"  
    android:installLocation="internalOnly"  
    android:sharedUserId="android.uid.system" >  
也有:
android:sharedUserId="android.uid.system"
这个在前面已经说过了,所以我们现在做的还是将其进行系统签名,具体方法就不多说了,同上

下面是运行的结果图:



Demo工程下载地址:

http://download.csdn.net/detail/jiangwei0910410003/7584429

下载之后的工程导入之后需要进行的几步操作和前面的是一模一样的,这里就不做解释了~~


总结:上面就介绍了实现静态安装和卸载的功能,其实还有其他的方法,比如我们可以将需要默认安装的apk文件直接拷贝到目录:

/data/app,因为我们知道所有用户安装的应用都是放在这个目录中的,但是经过测试发现,默认安装是没有问题的,直接将其拷贝

即可,但是在进行卸载的时候有点问题,我们直接删除apk文件的话,手机中还是有这个应用的图标的,但是我们点击打开的时候会

出现死机的情况,就相当于我们在Window系统中误删了一个文件之后打不开程序的结果一样,所以这种卸载还是不靠谱的,不建议

使用,而且这种方式的话还需要获取手机的root权限


待解决的问题:

1. 上面我们可以看到我们使用的是4.4版本进行签名的,只能安装到系统是4.4版本的机子上,这个有待考证,因为我们开发的应用不可能只能装到指定的版本中,必须是所有的系统都能进行安装(比如豌豆荚就可以),所以我就做了一个假设,是不是低版本的签名文件进行系统签名之后的apk可以安装到高版本系统中,那么这样就好办了,我们可以下载Android2.2(因为现在市面上最低的版本是2.2了)源码,得到他的签名文件,或者从网上搜索到这个版本的签名文件(至今未找到,如果有找到的请分享,谢谢!!)

2. 还有一个问题就是上述的测试环境都是在手机或者模拟器都是root过了,有待考证的是没有root的手机会不会安装时出现问题~~


上述的blog是纠结了我几个月的时间才解决的,所以我真心想说的一句话就是:做事千万不要放弃,办法总比问题多,一定要坚持~~,其实上面遇到的最大的问题就是在下载源码过程(没有技术可言,就是考验我们的耐心,同时网络也是一个重要的原因,这里由于某些原因,我下载的是4.4版本的源码,共13G,这里就不公开下载地址了,如果真心需要请留言,我可以共享一下~~),还有就是编译过程,我花费了一周的时间,因为在这个过程中可以说是千难万险,什么问题都有,我重新编译好几次~~

分享到:
评论

相关推荐

    Android应用卸载之后打开Android浏览器问卷调查

    总结,要实现在Android应用卸载后打开问卷调查,我们需要创建一个静态BroadcastReceiver监听ACTION_PACKAGE_REMOVED广播,然后在接收到应用卸载事件时,使用Intent打开预设的浏览器链接。整个过程涉及到Android应用...

    浅谈Android中关于静态变量(static)的使用问题

    在Android开发中,静态变量(`static`)的使用是一个重要的议题,因为它涉及到应用程序的内存管理、生命周期以及可能引发的问题。下面将详细讨论以下几个方面: 1. **静态变量的生命周期**: - 静态变量在类被加载...

    监听自身应用卸载,并在卸载之后,使用libcurl三方库进行一次三方请求,或者启动网页的实例工程。.zip

    在Android开发中,有时我们需要对应用的生命周期有更深入的控制,例如,当用户卸载应用时执行一些操作。这个实例工程就是针对这样的需求而设计的,它展示了如何监听自身应用的卸载事件,并在卸载后利用libcurl库发送...

    Android 安全与权限 Security Permission

    * 应用程序的安装和卸载:应用程序的安装和卸载需要 SYSTEM_ALERT_WINDOW 权限和 INSTALL_PACKAGES 权限。 * 网络连接:应用程序需要 INTERNET 权限来连接互联网。 * 文件操作:应用程序需要 WRITE_EXTERNAL_STORAGE...

    安卓安装卸载相关-一个AndroidSO文件保护加固的示例里面有so文件加密解密的示例和源码.rar

    在Android开发中,SO(Shared Object)文件是用于存储C/C++编译后的二进制代码,它们在应用运行时被加载,提供了原生库的支持。SO文件的保护和加固对于防止逆向工程、篡改以及盗版至关重要。本示例提供了一种Android...

    android打开另一App,并监测运行情况

    在Android平台上,开发人员可以实现一个功能,即从自己的应用程序中启动另一个应用,并且能够监控目标应用的运行状态。这通常涉及到Intent的使用,Activity管理,以及系统广播接收器。以下将详细介绍这些知识点: 1...

    Android底层与框架学习步骤[整理].pdf

    Android的包管理服务负责应用的安装、更新和卸载。系统通过PackageManager类来访问和管理安装的应用包。 11. Android与Linux内核: Android基于Linux内核,应用了Linux内核的诸多特性,例如Ashmem(匿名共享内存...

    android5.1 ethernet

    4. **静态IP配置**:Android 5.1支持静态IP配置,允许用户手动设定IP地址、子网掩码、默认网关和DNS服务器。这部分源码位于Settings应用或NetworkService中,涉及对`netd`服务的调用,通过`setInterfaceConfig`命令...

    新版Android开发教程.rar

    的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 • 应用程序框架 支持组件的重用与替换 • Dalvik Dalvik Dalvik Dalvik 虚拟机 专为移动设备优化 • ...

    插件化动态加载apk

    在Android开发领域,插件化动态加载apk是一种高级技术,它允许应用程序在运行时加载和卸载未预先安装的apk,以实现功能扩展或者界面皮肤更换等效果。这种技术极大地提高了应用的灵活性和可维护性,同时减少了用户...

    Android高级应用源码-判断双SD卡_CheckDoubleSDCard.zip

    源码中可能还会涉及到`Environment`类,它是Android提供的一组静态方法,用于处理与文件系统相关的操作。例如,`Environment.getExternalStorageState()`用于获取设备的默认外部存储状态,而`Environment....

    Android第一行代码源码 BroadcastBestPractice.rar

    在Android开发中,广播(Broadcast)是系统用来在应用程序之间传递消息的一种机制。"Android第一行代码源码 ...通过学习和实践这些知识点,开发者将能够更好地在Android应用中利用广播实现跨组件通信。

    android获取短信验证码实例详细好用

    5. **动态注册和卸载Receiver**:由于权限问题,从Android 8.0(API级别26)开始,非默认应用不能在启动时静态注册接收器。因此,你需要在运行时动态注册,并在不需要时通过`unregisterReceiver()`卸载。 6. **处理...

    Android中的广播、服务、数据库、通知、包等术语的原理和介绍(图解)

    PackageManager是Android系统用于管理和查询应用包的API,可以用来安装、卸载应用,获取应用信息,甚至控制权限。AndroidManifest.xml文件是每个应用的核心配置文件,包含了应用的所有组件声明、权限请求、版本信息...

    Android glide框架加载gif图片.rar

    在Android应用中,尤其是在滚动列表或者网格视图时,这种特性尤为重要,因为频繁的图片加载和卸载可能导致性能问题。 1. **集成Glide** 要在项目中使用Glide,首先需要在`build.gradle`文件中添加依赖: ```...

    USB之android_Vold_分析

    - **Vold的定位**:Vold在Android系统中的地位非常重要,主要用于管理和控制外部存储设备的挂载、卸载等操作。 - **Vold与udev的区别**:虽然两者在功能上有很多相似之处,但Vold针对Android的特性和需求进行了优化...

    详解React Native监听Android回退按键与程序化退出应用

    在Android系统中,用户按下回退键时,默认的行为是返回上一个页面,如果应用处于后台,则不会真正退出,而是继续在后台运行。然而,在某些情况下,开发者需要根据应用的特定需求来定制回退键的行为,比如在用户按下...

    安卓broadcastReceiver的使用

    在Android系统中,BroadcastReceiver(广播接收者)是四大组件之一,它负责监听系统或应用程序发布的广播事件,并根据这些事件执行相应的操作。BroadcastReceiver有两种注册方式:静态注册和动态注册,每种方式都有...

    android+java面试

    【Android面试核心知识点详解】 1. **Android四大组件** ...以上内容涵盖了Android开发中的关键知识点,对于面试和实际工作都具有很高的参考价值。理解并掌握这些概念,将有助于提升Android开发技能和应对面试挑战。

    360黑科技DroidPlugin.zip

    DroidPlugin 是360手机助手在 Android 系统上实现了一种新的插件机制:它可以在无需安装、修改的情况下运行APK文件,此机制对改进大型APP的架构,实现多团队协作开发具有一定的好处。定义:HOST程序:插件的宿主。...

Global site tag (gtag.js) - Google Analytics