GeekBand第九周笔记

1.为什么使用多进程

android中一个应用默认是一个进程,但是android平台对每个进程有内存限制,如24M等。如果应用有两个进程,则该应该的总内存限制是2*24m。

使用多进程就可以使得我们一个apk所使用的内存限制加大几倍。所以可以借此图片平台对应用的内存限制,比如一些要对图片、视频、大文件进程处理的好内存的应用可以考虑用多进程来解决应用操作不流畅问题。

2.进程,多进程是什么

进程是资源分配的基本单位。所有与该进程有关的资源,都被记录在进程控制块PCB中。以表示 该进程拥有这些资源或正在使用他们。

进程,也是抢占处理机的调度单位,它拥有一个完整的虚拟地址空间。当进程发生调度时,不同的进程拥有不同的虚拟地址空间,而同一进程内的不同线程共享同一地址空间。

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

进程的概念主要有两点:第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体,我们称其为进程。

3.进程的特性

  • 一个进程可以有多个线程
  • 进程间内存的不可见性
  • android平台对进程是有内存限制的

4.进程的等级

a.前台进程
用户当前正在做的事情需要这个进程。如果满足下面的条件,一个进程就被认为是前台进程:

这个进程拥有一个正在与用户交互的Activity(这个Activity的onResume()方法被调用)。

这个进程拥有一个绑定到正在与用户交互的activity上的Service。

这个进程拥有一个前台运行的Service — service调用了方法startForeground().

这个进程拥有一个正在执行其任何一个生命周期回调方法(onCreate(),onStart(),或onDestroy())的Service。

这个进程拥有正在执行其onReceive()方法的BroadcastReceiver。

通常,在任何时间点,只有很少的前台进程存在。它们只有在达到无法调合的矛盾时才会被杀--如内存太小而不能继续运行时。通常,到了这时,设备就达到了一个内存分页调度状态,所以需要杀一些前台进程来保证用户界面的反应

b.可见进程
一个进程不拥有运行于前台的组件,但是依然能影响用户所见。满足下列条件时,进程即为可见:

这个进程拥有一个不在前台但仍可见的Activity(它的onPause()方法被调用)。当一个前台activity启动一个对话框时,就出了这种情况。

一个可见进程被认为是极其重要的。并且,除非只有杀掉它才可以保证所有前台进程的运行,否则是不能动它的。

这个进程拥有一个绑定到可见activity的Service。

c.服务进程

运行着一个被startService()所启动的service。

尽管一个服务进程不直接影响用户所见,但是它们通常做一些用户关心的事情(比如播放音乐或下载数据),所以系统不到前台进程和可见进程活不下去时不会杀它。

d.后台进程
一个进程拥有一个当前不可见的activity(activity的onStop()方法被调用)。

这样的进程们不会直接影响到用户体验,所以系统可以在任意时刻杀了它们从而为前台、可见、以及服务进程们提供存储空间。通常有很多后台进程在运行。它们被保存在一个LRU(最近最少使用)列表中来确保拥有最近刚被看到的activity的进程最后被杀。如果一个activity正确的实现了它的生命周期方法,并保存了它的当前状态,那么杀死它的进程将不会对用户的可视化体验造成影响。因为当用户返回到这个activity时,这个activity会恢复它所有的可见状态。

e.空进程
一个进程不拥有入何active组件。

保留这类进程的唯一理由是高速缓存,这样可以提高下一次一个组件要运行它时的启动速度。系统经常为了平衡在进程高速缓存和底层的内核高速缓存之间的整体系统资源而杀死它们。

5怎么使用多进程

 我们可以将一些组件运行在其他进程中,并且可以为任意的进程添加线程。组件运行在哪个进程中是在manifest文件里设置的,其中,,和都有一个process属性来指定该组件运行在哪个进程之中。我们可以设置这个属性,使得每个组件运行在它们自己的进程中,或是几个组件共同享用一个进程,或是不共同享用。元素也有一个process属性,用来指定所有的组件的默认属性。
 
a.新建立一个进程,把下面代码添加到AndroidManifests的组件标签中

android:process="com.my.process"

b.命名规则,在后面添加“:”相当于在进程空间里附加一个进程

android:process=":push"

给该组件添加标签后,它就会运行在一个新的进程中。

插播。
application,主应用,有自己的名字,可以自定义的。
a.建类,继承Application。
该类中可以做一些,全局初始化的东西。程序刚开始走applictation ,onCreate方法。
全局初始化,多进程会初始化多遍。

public class MainApplication extends Application {

@Override
public void onCreate() {
super.onCreate();
}
}

b.AndroidManifest.xml文件中,application标签里

android:name=".MainApplication"

进程的内存又是不可见的,进程间不能互相使用资源。所以就涉及到进程间通信。

6.进程间通信

多进程间的通信 IPC 一般都会用service进行沟通。两种方式:

a. 多进程,单线程,使用Messenger
b. 多进程,多线程,使用 AIDL

Messenger

1.新建Serviece

public class MessengerService extends Service {
//    参数可以是Handler,或IBinder
Messenger mMessenger=new Messenger(new IncomingHandler());

    class IncomingHandler extends Handler{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
            switch (msg.what){
case 0:
break;
}
        }
    }
@Nullable
    @Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}

2.注册Service

<service android:name=".messenger.MessengerService"
android:process="com.exa.messenger.service"/>

3.新建 MessengerActivity

public class MessengerActivity extends Activity {
private ServiceConnection mServiceConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMessenger = new Messenger(service);
}

@Override
public void onServiceDisconnected(ComponentName name) {

        }
    };
 private Messenger mMessenger;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bindService(new Intent(this,MessengerService.class),
mServiceConnection, Context.BIND_AUTO_CREATE);
        if(mMessenger!=null){
            Message message=Message.obtain(null,0,"hello");
            try {
                mMessenger.send(message);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
     }
  }

AIDL的使用

1.main文件夹下,新建package aidl .然后在该包下建 新建 aidl file
2. 在app. build.generated. source.里面有aidl和debug.然后运行该程序,debug下面就会出现IMyAidlInterface。
3.在 main.java. com.exa.threadtest包下,再新建一个aidl包,然后新建类AIDLService

public class AIDLService extends Service {

    IMyAidlInterface.Stub mStub=new IMyAidlInterface.Stub() {
    @Override
    public void basicTypes(int anInt, long aLong, boolean aBoolean,    float aFloat, double aDouble, String aString) throws RemoteException {

        }

    @Override
    public String getName(String nickName) throws RemoteException {
        return nickName+"aidl_hahaha";
    }
 };
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mStub;
    }
}

4.在activity中

public class AIDLActivity extends Activity {
    ServiceConnection mServiceConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}

@Override
public void onServiceDisconnected(ComponentName name) {

        }
    };
    private IMyAidlInterface mMyAidlInterface;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aidl);
findViewById(R.id.aidl).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

if(mMyAidlInterface!=null){
try {
                        String name=mMyAidlInterface.getName("nike 0 cam");
Toast.makeText(AIDLActivity.this,name,Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
                        e.printStackTrace();
}
                }
                bindService(new Intent(AIDLActivity.this,AIDLService.class)
,mServiceConnection, Context.BIND_AUTO_CREATE);
}
        });
}
}

Service
介绍另一部分
种类:
Locate Service, 依附于主进程,节约资源。不需要进程间通信。
Remote Service, 就是另一个进程,独立的进程。使用较复杂,系统常驻的服务。

类型:
前台:在通知栏显示的服务,就是前台服务,使用Notification.
后台:默认的就是后台服务

老师的setLatesteEventInfo方法已经不能使用,所以此处使用Builder来构建Notification。

public class MusicService extends Service {
    private static final int NOTIFICATION_ID = 101; // 如果id设置为0,会导致不能设置为前台service

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void onCreate() {
        super.onCreate();

        PendingIntent pendingIntent=PendingIntent.getActivity(this,12,new Intent(this,MainActivity.class),PendingIntent.FLAG_UPDATE_CURRENT);

        Notification.Builder builder = new Notification.Builder(this);
        builder.setSmallIcon(R.drawable. ic_launcher);//设置电源栏图标
        builder.setContentTitle( "发现周边优惠、畅享免费Wi-Fi" );//拉开之后,标题
        builder.setContentText( "【智慧生活】发现城市的智慧" );//内容
        builder.setWhen(System.currentTimeMillis());// 时间
        builder.setOngoing(true);// 正在运行的Ongoing
        builder.setContentIntent(pendingIntent);
        Notification notification = builder.build();

        startForeground(11,notification);//开启前台的方法,标识符(不要0),通知。

    }
}

启动前台进程
startForeground();
停止前台进程
stopForeground();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值