您的位置:首页 > 移动开发 > Android开发

Android BroadCast (一)

2015-06-01 21:29 477 查看

Android BroadCast (一)

我们先来看看网络上对
BroadCast
较为普遍的看法:

到底怎么看待BroadCast

如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由 Service 来完成 . 这里不能使用子线程来解决 , 因为 BroadcastReceiver 的生命周期很短 , 子线程可能还没有结束

BroadcastReceiver 就先结束了 .BroadcastReceiver 一旦结束 , 此时 BroadcastReceiver 的

所在进程很容易在系统需要内存时被优先杀死 , 因为它属于空进程 ( 没有任何活动组件的进程 ). 如果它的宿主进程被杀死 , 那么正在工作的子线程也会被杀死 .

上面这个看法是对还是错,还是并不完善?

Android Process

先来看看Android官方文档对于进程的几种定义:

To determine which processes should be killed when low on memory, Android places each process into an “importance hierarchy” based on the components running in them and the state of those components. These process types are (in order of importance):

A foreground process

A foreground process is one that is required for what the user is currently doing. Various application components can cause its containing process to be considered foreground in different ways. A process is considered to be in the foreground if any of the following conditions hold:

It is running an Activity at the top of the screen that the user is interacting with (its onResume() method has been called).

It has a BroadcastReceiver that is currently running (its BroadcastReceiver.onReceive() method is executing).

It has a Service that is currently executing code in one of its callbacks (Service.onCreate(),Service.onStart(), or Service.onDestroy()).

There will only ever be a few such processes in the system, and these will only be killed as a last resort if memory is so low that not even these processes can continue to run. Generally, at this point, the device has reached a memory paging state, so this action is required in order to keep the user interface responsive.

A visible process

A visible process is one holding an Activity that is visible to the user on-screen but not in the foreground (itsonPause() method has been called). This may occur, for example, if the foreground Activity is displayed as a dialog that allows the previous Activity to be seen behind it. Such a process is considered extremely important and will not be killed unless doing so is required to keep all foreground processes running.

A service process

A service process is one holding a Service that has been started with the startService() method. Though these processes are not directly visible to the user, they are generally doing things that the user cares about (such as background mp3 playback or background network data upload or download), so the system will always keep such processes running unless there is not enough memory to retain all foreground and visible process.

A background process

A background process is one holding an Activity that is not currently visible to the user (its onStop() method has been called). These processes have no direct impact on the user experience. Provided they implement their Activity life-cycle correctly (see Activity for more details), the system can kill such processes at any time to reclaim memory for one of the three previous processes types. Usually there are many of these processes running, so they are kept in an LRU list to ensure the process that was most recently seen by the user is the last to be killed when running low on memory.

An empty process

An empty process is one that doesn’t hold any active application components. The only reason to keep such a process around is as a cache to improve startup time the next time a component of its application needs to run. As such, the system will often kill these processes in order to balance overall system resources between these empty cached processes and the underlying kernel caches.

上面将Android的5中进程都描述了一遍。从高优先级到低优先级分别是:

前台进程

Activity在生命周期内,并且onResume()执行过,此时Activity获得焦点。

Broadcast在生命周期内onReceive()正在执行。

Service.onCreate(),Service.onStart(), or Service.onDestroy()任何一个方法被执行。

归结为一句话就是 Applicaton的三大组件在运行中,这个时候就是前台进程。

可见进程

当Activity在生命周期中,并且onPause执行过,此时Activity失去焦点。

服务进程

当Service startService()以后,

后台进程

当Activity在生命周期中,并且onStop执行过,此时Activity不可见。

空进程

该进程木有Application的任何组件。

结论

当Android资源紧张的时候会按照从低到高优先级回收这些进程。

对于一个尚未在Mainfest中配置各个组件属于哪个进程的情况下,一个Application默认会将四大组件放在同一个Process中。而对于这样一个项目来说,一般会有个Activity组件存在,所以此时的Process是上面的哪种情况呢?

A foreground process 当该Acticity是活动的,获得焦点

A visible process 当该Activity是活动的,但是被遮挡,失去焦点

A background process 当该Activity不是活动的,被完全盖住

所以这样一个Process无论如何都不会是个空进程,这一点是肯定的,


此时在
Broadcast
Onreceive()
方法中开启一个子线程去做异步操作是可行的。

对于比较特殊的项目来说,没有任何
Activity
存在,也没有任何
Service
存在,那么在执行到
OnReceive()
,此时Apk进程是一个
A foreground process
,而当执行结束以后,此时Apk进程很可能是
An empty process
,所以系统很容易结束掉这个Apk进程,所以在
OnReceive()
中启用一个子线程是不安全的,如果此时在
OnReceive()
中启用
Service
,那么起码在
OnReceive()
中执行结束以后,Apk进程还可以处于
A service process
,所以不可能被系统无端Kill掉



关于
Broadcast
的基本情况介绍到这里,接下来会继续介绍发送广播的两种方式:Android BroadCast (二)

附件: 这个给出个小Demo

[code]@Override
    protected void onCreate(final Application application)
{
    IntentFilter accessIntentFilter = new IntentFilter();
                accessIntentFilter.addAction(BaseThinAdobePassAccount.K.S_ADOBEPASS_BROADCAST_CATION_LOGIN_STATUS_CHANGED);
                application.registerReceiver(mAccessReceiver, accessIntentFilter);
}

private BroadcastReceiver mAccessReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        if (intent.getAction().equalsIgnoreCase(BaseThinAdobePassAccount.K.S_ADOBEPASS_BROADCAST_CATION_LOGIN_STATUS_CHANGED))
        {
            schoolCheck();
        }
    }
};


先是注册了一个Receive,然后在Receive的onReceive方法中启用了一个新的线程循环的去检查,直到某一个条件满足就会停止检查

[code]private void schoolCheck()
{
    if (BTNAdobePassAccount.getInstance().isInitialized() && !BTNAdobePassAccount.getInstance().isLogin())
    {
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    String response = executeBTNSchoolCheck();

                    if (!TextUtils.isEmpty(response))
                    {
                        mHandler.removeCallbacks(mSchoolCheckRunnable);

                        mHandler.postDelayed(mSchoolCheckRunnable, IntervalUtil.getInterval("schoolCheck"));
                    }

                    if (!TextUtils.equals(mCampusId, response))
                    {
                        LocalBroadcastManager.getInstance(getApplication()).sendBroadcast(new Intent(Constants.FILTER_SCHOOLCHECK));
                    }

                    mCampusId = response;
                }
                catch (NLSException e)
                {
                    e.printStackTrace();
                }
            }
        }).start();

    }
    else
    {
        mCampusId = null;

        mHandler.removeCallbacks(mSchoolCheckRunnable);
    }
}

private final Runnable mSchoolCheckRunnable = new Runnable()
{
    @Override
    public void run()
    {
        schoolCheck();
    }
};


这里是注册广播,一般这里做的事情比较多,因为广播接收者会根据接收到的信息作出响应。而发送广播则简单的多了:

[code]getActivity().sendBroadcast(
                    new Intent(Extras.key(BaseThinAdobePassAccount.K.S_ADOBEPASS_BROADCAST_CATION_LOGIN_STATUS_CHANGED)));
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: