一个小程序,实际中用到的,目的是用一个Activity 启动另一个Activity,然后再kill 掉。
刚好中间又涉及到查询系统中进程的信息,这里就一并总结一下,方便以后使用。
注意:关于用Activity kill 另一个 Activity,在网上查了好几种方法,包括 (restartPackage, killBackgroundProcesses, forceStopPackage),该设置的权限基本都设置了,但在本机的工作环境中没有一个生效的。这里只是简单的记录了一下的使用方式,可以进一步找找失败原因。
Apk 1 可以启动 Apk2,查询进程信息,结束进程 Apk 2
Apk 2
Intent :
一个Intent对象的主要作用是用来描述我们将要做什么样的操作(这里操作的范围主要指的是Activity之间或程序之间的)。
例如我们想用startActivity 启动一个Activity,发送广播到任何一个感兴趣的BroadcastReceiver。startService或bindService到后台的Service程序。都可以看做是我们想要做的操作。
Intent 的结构中主要包括两个成员
action:我们要执行什么样的操作:ACTION_VIEW, ACTION_EDIT, ACTION_MAIN
data:在执行操作的过程中需要的数据。
Bundle:
Bundle的作用像别针一样,文档中的解释是把String映射到一些可打包的类型当中。在程序中主要还是作为传值的媒介。
ActivityManager:
用于操作系统中所有activitiy。看文档中的介绍还是非常有用的。例如取进程ID,内存信息等等。
这些类主要还是在于应用,程序里使用起来还是很清楚的。
package com.example.apk_invoke_app_1; import java.util.List; import android.os.Bundle; import android.os.Debug; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { private ActivityManager activityManager = null; private Button m_btnNewApp; private Button m_btnListAllApp; private Button m_btnEndApp; private List m_appProcessList; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.activityManager = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE); TextView texView= (TextView) findViewById(R.id.text1); texView.setText("My PID is: " + android.os.Process.myPid()); m_btnNewApp = (Button)findViewById(R.id.btn_startNew); m_btnListAllApp = (Button)findViewById(R.id.btn_listAll); m_btnEndApp = (Button)findViewById(R.id.btn_End); m_btnNewApp.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { ComponentName componetName = new ComponentName( //这个是另外一个应用程序的包名 "com.example.apk_invoke_app_2", //这个参数是要启动的Activity "com.example.apk_invoke_app_2.MainActivity"); Intent intent= new Intent(); //我们给他添加一个参数表示从apk1传过去的 Bundle bundle = new Bundle(); bundle.putString("arge1", "这是跳转过来的!来自apk1"); intent.putExtras(bundle); intent.setComponent(componetName); startActivity(intent); } }); m_btnListAllApp.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { listProcess(); } }); m_btnEndApp.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { killProcessByName("com.example.apk_invoke_app_2"); } }); } public void listProcess() { m_appProcessList = activityManager.getRunningAppProcesses(); for(int i=0; i<m_appProcessList.size(); i++) { RunningAppProcessInfo appProcessInfo = (RunningAppProcessInfo) m_appProcessList.get(i); //进程ID int pid = appProcessInfo.pid; //用户ID,类似于Linux的权限不同,ID也就不同, 比如root int uid = appProcessInfo.uid; //进程名,默认是包名或者由属性android:process=""指定 String processName = appProcessInfo.processName; //获得该进程占用的内存 int[] memPid = new int[]{ pid }; //此MemoryInfo位于android.os.Debug.MemoryInfo包中,用来统计进程的内存信息 Debug.MemoryInfo[] memoryInfo = activityManager.getProcessMemoryInfo(memPid); //获取进程占内存用信息kb单位 int memSize = memoryInfo[0].dalvikPrivateDirty; System.out.println("process name: " + processName + " pid: " + pid + " uid: " + uid + " memory size is -->" + memSize + "kb"); //获得每个进程里运行的应用程序(包),即每个应用程序的包名 String[] packageList = appProcessInfo.pkgList; for(String pkg : packageList) { System.out.println("package name " + pkg + " in process id is -->" + pid); } } } public void killProcessByName(String killProcessName) { System.out.println("killProcessByName()..."); listProcess(); for(int i=0; i<m_appProcessList.size(); i++) { RunningAppProcessInfo appProcessInfo = (RunningAppProcessInfo) m_appProcessList.get(i); //进程ID int pid = appProcessInfo.pid; //用户ID,类似于Linux的权限不同,ID也就不同, 比如root int uid = appProcessInfo.uid; //进程名,默认是包名或者由属性android:process=""指定 String processName = appProcessInfo.processName; //获得每个进程里运行的应用程序(包),即每个应用程序的包名 String[] packageList = appProcessInfo.pkgList; for(String pkg : packageList) { System.out.println("package name " + pkg + " in process id is -->" + pid); } if(killProcessName.equals(processName)) { System.out.println("===============killProcess pid-->" + pid); android.os.Process.killProcess(pid); } } } }
在程序中尝试着用killBackgroundProcesses来结束 apk_invoke_app_2,在模拟器中并不起作用。在log中可以看到它给目标进程发送了一个结束信号。
在虚拟机的测试环境中还尝试了几种其他的方式,但都不起作用。说不定在实际设备上是可以工作的。
这里先记录下来,以后方便查找。