Android文档——进程优先级与线程

最近看了Android 开发者文档中的线程和进程方面的内容,看后感觉Android的设计非常的巧妙与强大。将学习到的知识总结如下:

文档中的进程内容提到了进程优先级,我觉得很重要,对于我们理解Android的进程有很大的帮助:

原文附上:

Processes

By default, all components of the same application run in the same process and most applications should not change this. However, if you find that you need to control which process a certain component belongs to, you can do so in the manifest file.

The manifest entry for each type of component element—<activity>, <service>, <receiver>, and <provider>—supports an android:process attribute that can specify a process in which that component should run. You can set this attribute so that each component runs in its own process or so that some components share a process while others do not. You can also set android:process so that components of different applications run in the same process—provided that the applications share the same Linux user ID and are signed with the same certificates.

The <application> element also supports an android:process attribute, to set a default value that applies to all components.

Android might decide to shut down a process at some point, when memory is low and required by other processes that are more immediately serving the user. Application components running in the process that's killed are consequently destroyed. A process is started again for those components when there's again work for them to do.

When deciding which processes to kill, the Android system weighs their relative importance to the user. For example, it more readily shuts down a process hosting activities that are no longer visible on screen, compared to a process hosting visible activities. The decision whether to terminate a process, therefore, depends on the state of the components running in that process. The rules used to decide which processes to terminate is discussed below.
Process lifecycle

The Android system tries to maintain an application process for as long as possible, but eventually needs to remove old processes to reclaim memory for new or more important processes. To determine which processes to keep and which to kill, the system places each process into an "importance hierarchy" based on the components running in the process and the state of those components. Processes with the lowest importance are eliminated first, then those with the next lowest importance, and so on, as necessary to recover system resources.

There are five levels in the importance hierarchy. The following list presents the different types of processes in order of importance (the first process is most important and is killed last):

    Foreground process

    A process that is required for what the user is currently doing. A process is considered to be in the foreground if any of the following conditions are true:
        It hosts an Activity that the user is interacting with (the Activity's onResume() method has been called).
        It hosts a Service that's bound to the activity that the user is interacting with.
        It hosts a Service that's running "in the foreground"—the service has called startForeground().
        It hosts a Service that's executing one of its lifecycle callbacks (onCreate(), onStart(), or onDestroy()).
        It hosts a BroadcastReceiver that's executing its onReceive() method.

    Generally, only a few foreground processes exist at any given time. They are killed only as a last resort—if memory is so low that they cannot all continue to run. Generally, at that point, the device has reached a memory paging state, so killing some foreground processes is required to keep the user interface responsive.
    Visible process

    A process that doesn't have any foreground components, but still can affect what the user sees on screen. A process is considered to be visible if either of the following conditions are true:
        It hosts an Activity that is not in the foreground, but is still visible to the user (its onPause() method has been called). This might occur, for example, if the foreground activity started a dialog, which allows the previous activity to be seen behind it.
        It hosts a Service that's bound to a visible (or foreground) activity.

    A visible process is considered extremely important and will not be killed unless doing so is required to keep all foreground processes running.
    Service process

    A process that is running a service that has been started with the startService() method and does not fall into either of the two higher categories. Although service processes are not directly tied to anything the user sees, they are generally doing things that the user cares about (such as playing music in the background or downloading data on the network), so the system keeps them running unless there's not enough memory to retain them along with all foreground and visible processes.
    Background process

    A process holding an activity that's not currently visible to the user (the activity's onStop() method has been called). These processes have no direct impact on the user experience, and the system can kill them at any time to reclaim memory for a foreground, visible, or service process. Usually there are many background processes running, so they are kept in an LRU (least recently used) list to ensure that the process with the activity that was most recently seen by the user is the last to be killed. If an activity implements its lifecycle methods correctly, and saves its current state, killing its process will not have a visible effect on the user experience, because when the user navigates back to the activity, the activity restores all of its visible state. See the Activities document for information about saving and restoring state.
    Empty process

    A process that doesn't hold any active application components. The only reason to keep this kind of process alive is for caching purposes, to improve startup time the next time a component needs to run in it. The system often kills these processes in order to balance overall system resources between process caches and the underlying kernel caches.

Android ranks a process at the highest level it can, based upon the importance of the components currently active in the process. For example, if a process hosts a service and a visible activity, the process is ranked as a visible process, not a service process.


文档已经说明了

进程优先级

文档的解释 Doc
   
   
The manifest entry for each type of component element—<activity>, <service>, <receiver>, and <provider>—supports an android:process attribute that can specify a process in which that component should run. You can set this attribute so that each component runs in its own process or so that some components share a process while others do not. You can also set android:process so that components of different applications run in the same processprovided that the applications share the same Linux user ID and are signed with the same certificates
通过文档可以知道,可以通过Android的清单文件可以为android的组件 例如 activity、service、receiver指定组件运行的进程。通过设置  android:progress  设置此属性可以让不同的应用程序的组件运行在相同的进程中,多个应用程序共享相同的Linux的进程。
   
   
Android might decide to shut down a process at some point, when memory is low and required by other processes that are more immediately serving the user. Application components running in the process that's killed are consequently destroyed. A process is started again for those components when there's again work for them to do.
 
When deciding which processes to kill, the Android system weighs their relative importance to the user. For example, it more readily shuts down a process hosting activities that are no longer visible on screen, compared to a process hosting visible activities. The decision whether to terminate a process, therefore, depends on the state of the components running in that process. The rules used to decide which processes to terminate is discussed below.

Android能够决定关闭一个过程在某种程度上,当内存低,所需的其他进程,更直接的服务于用户。应用程序组件运行在这个过程中,也会因此被销毁。为这些组件重新开始一个过程时,再为他们工作。
当决定哪个进程的时候,Android系统向用户重他们的相对重要性。例如,它更容易关闭不在显示在屏幕上的activitys,而一个托管可见的activity progress 。因此,决定是否终止一个进程取决于组件中运行的状态的过程。终止进程的判定规则将是下面要讨论的。

Android中进程的生命周期:
Android系统视图保持应用程序的进程,但是最终需要删除旧的进程来回收内存。Android系统把每个进程都按照“重要性层次结构”进行划分。android分出了5个重要性的层次水平。分别是:

进程优先级

  • 前台进程
    • 拥有一个正在与用户交互的activity(onResume调用)的进程
    • 拥有一个与正在和用户交互的activity绑定的服务的进程
    • 拥有一个正在“运行于前台”的服务——服务的startForeground方法调用
    • 拥有一个正在执行以下三个生命周期方法中任意一个的服务(onCreate(), onStart(), or onDestroy())
    • 拥有一个正在执行onReceive方法的广播接收者的进程
  • 可见进程

    • 拥有一个不在前台,但是对用户依然可见的activity(onPause方法调用)的进程
    • 拥有一个与可见(或前台)activity绑定的服务的进程
  • 服务进程

    • 以startService()开启的服务,就是一个服务进程,尽管服务过程不直接与用户看到的任何东西,他们通常做一些用户关心的(比如在后台播放音乐或下载数据网络上的)。
  • 后台进程

    • 当一个activity执行onstop方法被调用,或者当前的activity用户不可见,这些进程没有影响到用户的体验,并且系统可以在任何时间来回收他们。
  • 空进程
    • 不包含任何活动的应用程序组件。这种进程还能存在的唯一的原因就是用于缓存。

线程:

文档说明当应用程序启动时,系统为应用程序创建一个线程的执行,称为“主要。 “这个线程非常重要,因为它负责把事件分发给相应的用户界面小部件,包括屏幕绘图事件。 也是您的应用程序与组件交互的线程从Android UI toolkit(组件从Android。 小部件和android。 视图包)。 因此,主线程有时也称为UI线程。
系统不为每个组件的实例创建一个单独的线程。所有组件运行在相同的进程中实例化UI线程,每个组件和系统调用分派线程。因此,应对系统回调的方法(如onKeyDown()报告用户操作或生命周期回调方法)在UI线程中运行的过程。
对于线程的安全 Android也做出了限定
此外,Andoid UI工具包不是线程安全的。所以,你不能操作UI允许从一个工人操作的用户界面UI线程。因此,仅仅有两个规则,Android的单线程模型:
不阻塞UI线程
不从外部访问Android UI toolkit UI线程
使用工作线程来不阻塞UI线程
     
     
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
mImageView.setImageBitmap(b);
}
}).start();
}
起初,这似乎工作好,因为它创建了一个新线程来处理网络操作。 然而,它违反了单线程模型的第二条规则:不要从外部访问Android UI toolkit UI片样品修改的ImageView工作线程而不是UI线程。 这可能导致未定义的和意想不到的行为,可以是困难和耗时的追踪。
要修复这个问题,Android提供了几种方法来从其他线程访问UI线程。这里是一个列表的方法,可以帮助:
Handler
然而,随着操作的复杂性,这种代码也会变得很复杂,很难维护。 工作线程来处理更复杂的交互,您可能会考虑使用一个Handler在你的工作线程,从UI线程处理消息交付。 也许最好的解决方案,是扩展AsyncTask类,这简化了工作线程的执行任务,需要与用户界面交互。
AsyncTask
AsyncTask允许您执行异步工作在你的用户界面。它执行阻塞操作在一个工作线程,然后在UI线程上公布结果,不需要你自己处理线程和/或处理程序。
使用它,您必须子类AsyncTask,实现doInBackground()回调方法,运行在一个后台线程池。更新UI,你应该实现onPostExecute(),交付结果从doInBackground()和在UI线程中运行,所以您可以安全地更新UI。然后您可以运行任务从UI线程通过调用execute()。
     
     
public void onClick(View v) {
new DownloadImageTask().execute("http://example.com/image.png");
}
 
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}
 
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值