07 Activity启动另一个Activity 及 进程的信息查询

来源:互联网 发布:中华软件股份公司 编辑:程序博客网 时间:2024/06/18 05:44

简要说明:

一个小程序,实际中用到的,目的是用一个Activity 启动另一个Activity,然后再kill 掉。

刚好中间又涉及到查询系统中进程的信息,这里就一并总结一下,方便以后使用。

注意:关于用Activity kill 另一个 Activity,在网上查了好几种方法,包括 (restartPackage, killBackgroundProcesses, forceStopPackage),该设置的权限基本都设置了,但在本机的工作环境中没有一个生效的。这里只是简单的记录了一下的使用方式,可以进一步找找失败原因。


程序界面:

Apk 1  可以启动 Apk2,查询进程信息,结束进程 Apk 2

app_1_diagram


Apk 2

app_2_diagram


程序基本功能和 Android 函数说明

Intent : 

一个Intent对象的主要作用是用来描述我们将要做什么样的操作(这里操作的范围主要指的是Activity之间或程序之间的)。

例如我们想用startActivity 启动一个Activity,发送广播到任何一个感兴趣的BroadcastReceiver。startService或bindService到后台的Service程序。都可以看做是我们想要做的操作。

Intent 的结构中主要包括两个成员

action:我们要执行什么样的操作:ACTION_VIEW, ACTION_EDIT, ACTION_MAIN

data:在执行操作的过程中需要的数据。


Bundle:

Bundle的作用像别针一样,文档中的解释是把String映射到一些可打包的类型当中。在程序中主要还是作为传值的媒介。


ActivityManager:

用于操作系统中所有activitiy。看文档中的介绍还是非常有用的。例如取进程ID,内存信息等等。


这些类主要还是在于应用,程序里使用起来还是很清楚的。



APK 1 实例代码

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的运行结果

在程序中尝试着用killBackgroundProcesses来结束  apk_invoke_app_2,在模拟器中并不起作用。在log中可以看到它给目标进程发送了一个结束信号。


end_process_diam

在虚拟机的测试环境中还尝试了几种其他的方式,但都不起作用。说不定在实际设备上是可以工作的。

这里先记录下来,以后方便查找。


完整测试代码下载(包括 apk_invoke_app_1 和 apk_invoke_app_2 )