- 浏览: 6348807 次
- 性别:
- 来自: 一片神奇的土地
文章分类
- 全部博客 (745)
- JQuery (25)
- JS (33)
- 数据库 (59)
- Java基础 (56)
- JSON (8)
- XML (8)
- ireport (7)
- 设计模式 (10)
- 心情 (14)
- freemarker (1)
- 问题 (15)
- powerdesigner (2)
- CSS (15)
- DWR (4)
- tomcat (16)
- Hibernate (12)
- Oracle (7)
- Struts (7)
- Spring (34)
- JSP (23)
- 需学习 (64)
- 工具类库 (63)
- Maven (14)
- 笔试题 (34)
- 源码学习 (31)
- 多线程 (39)
- Android (32)
- 缓存 (20)
- SpringMVC (14)
- jQueryEasyUi (12)
- webservice-RPC (13)
- ant (1)
- ASP.NET (10)
- 正则表达式 (3)
- Linux (15)
- JBoss (1)
- EJB (3)
- UML (2)
- JMS (3)
- Flex (8)
- JSTL (2)
- 批处理 (5)
- JVM (16)
- 【工具】 (16)
- 数据结构 (29)
- HTTP/TCP/Socket (18)
- 微信 (1)
- tomcat源码学习 (15)
- Python (30)
- 主机 (2)
- 设计与架构 (19)
- thrift-RPC (2)
- nginx (6)
- 微信小程序 (0)
- 分布式+集群 (12)
- IO (1)
- 消息队列 (4)
- 存储过程 (8)
- redis (9)
- zookeeper (5)
- 海量数据 (5)
最新评论
-
360pluse:
技术更新,战术升级!Python爬虫案例实战从零开始一站通网盘 ...
Python爬虫实战:Scrapy豆瓣电影爬取 -
18335864773:
推荐用 pageoffice 组件生成 word 文件。
JAVA生成WORD工具类 -
jjhe369:
LISTD_ONE 写道起始地址为163.135.0.1 结束 ...
IP地址与CIDR -
baojunhu99:
private final int POOL_SIZE = 5 ...
使用CompletionService获取多线程返回值 -
LovingBaby:
胡说,javascript 运行时是单线程的,event lo ...
Ajax请求是否可以实现同步
1.Android进程基本知识:
我们先来了解下Android中的进程基本知识。
当一个程序第一次启动的时候,Android会启动一个LINUX进程和一个主线程。默认的情况下,所有该程序的组件都将在该进程和线程中运行。 同时,Android会为每个应用程序分配一个单独的LINUX用户。Android会尽量保留一个正在运行进程,只在内存资源出现不足 时,Android会尝试停止一些进程从而释放足够的资源给其他新的进程使用, 也能保证用户正在访问的当前进程有足够的资源去及时地响应用户的事件。
Android会根据进程中运行的组件类别以及组件的状态来判断该进程的重要性,Android会首先停止那些不重要的进程。按照重要性从高到低一共有五个级别:
前台进程
前台进程是用户当前正在使用的进程。只有一些前台进程可以在任何时候都存在。他们是最后一个被结束的,当内存低到根本连他们都不能运行的时候。一般来说, 在这种情况下,设备会进行内存调度,中止一些前台进程来保持对用户交互的响应。
可见进程
可见进程不包含前台的组件但是会在屏幕上显示一个可见的进程是的重要程度很高,除非前台进程需要获取它的资源,不然不会被中止。
服务进程
运行着一个通过startService() 方法启动的service,这个service不属于上面提到的2种更高重要性的。service所在的进程虽然对用户不是直接可见的,但是他们执行了用 户非常关注的任务(比如播放mp3,从网络下载数据)。只要前台进程和可见进程有足够的内存,系统不会回收他们。
后台进程
运行着一个对用户不可见的activity(调用过 onStop() 方法).这些进程对用户体验没有直接的影响,可以在服务进程、可见进程、前台进 程需要内存的时候回收。通常,系统中会有很多不可见进程在运行,他们被保存在LRU (least recently used) 列表中,以便内存不足的时候被第一时间回收。如果一个activity正 确的执行了它的生命周期,关闭这个进程对于用户体验没有太大的影响。
空进程
未运行任何程序组件。运行这些进程的唯一原因是作为一个缓存,缩短下次程序需要重新使用的启动时间。系统经常中止这些进程,这样可以调节程序缓存和系统缓存的平衡。
Android 对进程的重要性评级的时候,选取它最高的级别。另外,当被另外的一个进程依赖的时候,某个进程的级别可能会增高。一个为其他进程服务的进程永远不会比被服 务的进程重要级低。因为服务进程比后台activity进程重要级高,因此一个要进行耗时工作的activity最好启动一个service来做这个工 作,而不是开启一个子进程――特别是这个操作需要的时间比activity存在的时间还要长的时候。例如,在后台播放音乐,向网上上传摄像头拍到的图片, 使用service可以使进程最少获取到“服务进程”级别的重要级,而不用考虑activity目前是什么状态。broadcast receivers做费时的工作的时候,也应该启用一个服务而不是开一个线程。
2. 单线程模型
当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处 理。所以主线程通常又被叫做UI线程。
在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。
2.1 子线程更新UI Android的UI是单线程(Single-threaded)的。
为了避免拖住GUI,一些较费时的对象应该交给独立的线程去执行。如果幕后的线程来执行UI对象,Android就会发出错误讯息 CalledFromWrongThreadException。以后遇到这样的异常抛出时就要知道怎么回事了!
2.2 Message Queue
在单线程模型下,为了解决类似的问题,Android设计了一个Message Queue(消息队列), 线程间可以通过该Message Queue并结合Handler和Looper组件进行信息交换。下面将对它们进行分别介绍:
2.2.1. Message Message消息
理解为线程间交流的信息,处理数据后台线程需要更新UI,则发送Message内含一些数据给UI线程。
2.2.2. Handler Handler处理者
是Message的主要处理者,负责Message的发送,Message内容的执行处理。后台线程就是通过传进来的Handler对象引用来 sendMessage(Message)。而使用Handler,需要implement 该类的 handleMessage(Message) 方法,它是处理这些Message的操作内容,例如Update UI。通常需要子类化Handler来实现handleMessage方法。
2.2.3. Message Queue Message Queue消息队列
用来存放通过Handler发布的消息,按照先进先出执行。 每个message queue都会有一个对应的Handler。Handler会向message queue通过两种方法发送消息:sendMessage或post。这两种消息都会插在message queue队尾并按先进先出执行。但通过这两种方法发送的消息执行的方式略有不同:通过sendMessage发送的是一个message对象,会被 Handler的handleMessage()函数处理;而通过post方法发送的是一个runnable对象,则会自己执行。
2.2.4. Looper Looper是每条线程里的Message Queue的管家。
Android没有Global的Message Queue,而Android会自动替主线程(UI线程)建立Message Queue,但在子线程里并没有建立Message Queue。所以调用Looper.getMainLooper()得到的主线程的Looper不为NULL,但调用Looper.myLooper() 得到当前线程的Looper就有可能为NULL。
对于子线程使用Looper,API Doc提供了正确的使用方法:
package com.test; import android.os.Handler; import android.os.Looper; import android.os.Message; class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); // 创建本线程的Looper并创建一个MessageQueue mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); // 开始运行Looper,监听Message Queue } }
1. 在Looper.loop()方法运行开始后,循环地按照接收顺序取出Message Queue里面的非NULL的Message。
2. 一开始Message
Queue里面的Message都是NULL的。当Handler.sendMessage(Message)到Message
Queue,该函数里面设置了那个Message对象的target属性是当前的Handler对象。随后Looper取出了那个Message,则调用
该Message的target指向的Hander的dispatchMessage函数对Message进行处理。
在dispatchMessage方法里,如何处理Message则由用户指定,三个判断,优先级从高到低:
1) Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作;
2) Handler里面的mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理;
3) 处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息。
由此可见,我们实现的handleMessage方法是优先级最低的!
3. Handler处理完该Message (update UI) 后,Looper则设置该Message为NULL,以便回收!
3.Android另外提供了一个工具类:AsyncTask。
((Button) findViewById(R.id.load_AsyncTask)).setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view) { data = null; data = new ArrayList<String>(); adapter = null; //显示ProgressDialog放到AsyncTask.onPreExecute()里 //showDialog(PROGRESS_DIALOG); new ProgressTask().execute(data); } }); private class ProgressTask extends AsyncTask<ArrayList<String>, Void, Integer> { /* 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。 */ @Override protected void onPreExecute() { // 先显示ProgressDialog showDialog(PROGRESS_DIALOG); } /* 执行那些很耗时的后台计算工作。可以调用publishProgress方法来更新实时的任务进度。 */ @Override protected Integer doInBackground(ArrayList<String>... datas) { ArrayList<String> data = datas[0]; for (int i=0; i<8; i++) { data.add("ListItem"); } return STATE_FINISH; } /* * 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用, 后台的计算结果将通过该方法传递到UI * thread. */ @Override protected void onPostExecute(Integer result) { int state = result.intValue(); switch(state){ case STATE_FINISH: dismissDialog(PROGRESS_DIALOG); Toast.makeText(getApplicationContext(), "加载完成!", Toast.LENGTH_LONG).show(); adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, data ); setListAdapter(adapter); break; case STATE_ERROR: dismissDialog(PROGRESS_DIALOG); Toast.makeText(getApplicationContext(),"处理过程发生错误!",Toast.LENGTH_LONG).show(); adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, data ); setListAdapter(adapter); break; default: } }
- final ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
- am.restartPackage(getPackageName());
不要忘记了在配置文件中设置权限:
- <uses-permission android:name="android.permission.RESTART_PACKAGES"></uses-permission>
- Process.killProcess(Process.myPid());
- ActivityManager manager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
- manager.killBackgroundProcesses(getPackageName());
- //需要在xml中加入权限声明
- <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
- Method forceStopPackage = am.getClass().getDeclaredMethod("forceStopPackage", String.class);
- forceStopPackage.setAccessible(true);
- forceStopPackage.invoke(am, yourpkgname);
配置文件中需要添加定义:
- android:sharedUserId="android.uid.system"
另外需要再在配置文件添加权限:
- <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"></uses-permission>
package com.test.android; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.KeyEvent; /** * Andriod按返回键返回到主屏幕示例 */ public class MyTestProjectActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // event.getRepeatCount():按下返回键,同时没有重复 if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { Intent home = new Intent(Intent.ACTION_MAIN); home.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); home.addCategory(Intent.CATEGORY_HOME); startActivity(home); } return super.onKeyDown(keyCode, event); } }......
发表评论
-
选择照片和拍照
2018-06-13 15:31 1667Android拍照或从本地选择图片上传 Android ... -
PullToRefresh的简单使用
2018-05-31 16:06 1297Android下拉刷新控件--PullToRefresh的简 ... -
fragment内嵌fragment之间传值+切换fragment
2018-05-30 11:59 13444跳转: 从一个Fragment跳转到另一个Fragmen ... -
控件使用问题
2018-05-22 09:59 1549TextView最大长度限制,超出部分省略号显示 xml ... -
ViewPager+RadioGroup+TabLayout
2018-05-22 09:38 1120ViewPager: ViewPager 详解(五)-- ... -
网络请求工具类HttpUtils
2018-05-19 21:07 2421代码如下: import android.app.Acti ... -
android排版布局学习
2018-05-18 16:24 3888Android开发学习之路--UI之基本布局 andro ... -
[工具]-Android切图
2018-05-18 14:21 1517切图小科普!聊聊原生APP切图那些事儿 安卓APP设计规 ... -
【Android基础问题】
2018-05-18 13:49 7381、appcompat_v7: appcompat_v7 ... -
WebView使用
2018-05-17 17:42 1190Android:最全面的 Webvie ... -
《第一行代码》服务+AsyncTask+定时任务
2018-04-23 09:45 178714、服务 服务(Service)是 Androi ... -
《第一行代码》通知+接收拦截发送短信
2018-04-23 09:44 170213、通知 在活动里 ... -
《第一行代码》内容提供器
2018-04-20 16:08 128512、内容提供器 内容提供器(Content Pro ... -
《第一行代码》数据存储
2018-04-20 16:07 68311、数据存储 将数据存储到文件中 ope ... -
《第一行代码》广播
2018-04-20 15:34 99610、广播接收器(Broadcast Receive ... -
《第一行代码》控件、布局、碎片
2018-04-20 14:40 9148、控件 TextView: a ... -
【Android studio配置和错误】
2018-04-20 14:21 4045Gradle是一个基于Apache Ant和Apache ... -
《第一行代码》基础总结
2016-07-12 22:07 1913activity的生命周期—— ... -
《第一行代码》扩展总结
2016-06-29 15:28 1339Android更新UI的两种方法——handler与run ... -
Android快速开发工具类
2016-01-21 14:56 1995来源:http://blog.csdn.net/lmj62 ...
相关推荐
为了确保正确操作,需要熟悉Linux的进程和线程管理知识,以及对Android NDK的使用。 `adb shell ps -t -p -c`是一个用于查看系统中所有进程和线程的命令。`ps`命令列出当前系统的进程状态,`-t`选项表示按线程显示...
在Android系统中,进程和线程是应用程序运行的基础,它们决定了程序如何管理和执行任务。深入理解这两个概念对于优化应用性能、提高用户体验至关重要。 首先,我们要明白什么是进程。在计算机科学中,进程是程序的...
#### 二、多线程基础知识 ##### 1. 进程与线程的概念 **进程**:一个正在运行的应用程序或服务。在操作系统中,每个进程都有自己的独立内存空间和一组系统资源。进程之间可以通过进程间通信(IPC)进行数据交换。 ...
在Android开发中,多线程下载是一项常见的...开发者需要熟悉Android的并发编程模型,了解网络编程的基础知识,并掌握文件I/O的操作。通过这样的实践,不仅可以提高应用的性能,也能加深对Android系统底层机制的理解。
在Android平台上,多线程下载是一项重要的技术,它允许应用程序同时从服务器获取数据,从而显著提高了文件下载的速度和效率。本教程将深入讲解如何在Android环境中实现多线程下载功能,以及涉及的相关知识点。 首先...
第六章“AIDL与跨进程通信”(Thread_Ch06_AIDL_ok.pdf)深入讲解了Android进程间通信(IPC)的机制,特别是使用Android Interface Definition Language (AIDL)来创建服务间的数据交换接口。这部分内容对于开发涉及...
在Android平台上,多线程下载机制是提升应用性能和用户体验的关键技术之一,特别是在处理大文件如应用程序、视频或音频资源的下载场景中。通过利用多线程,我们可以将一个大文件分割成多个小部分,然后同时启动多个...
以上内容涵盖了Android中线程交互的基础知识,包括AsyncTask的使用、Binder机制的理解、Handler和MessageQueue在多线程通信中的角色,以及迭代器模式在数据处理中的应用。理解并熟练掌握这些知识点,对于成为一名...
首先,了解Android进程生命周期是基础。Android系统根据应用当前的活动状态将进程分为五类:前台进程、可见进程、服务进程、后台进程和空进程。系统通常会优先回收空进程,然后是后台进程,以此类推,直到资源充足。...
以上就是关于Android进程注入的基本概念和关键技术点,这个领域涉及到的知识广泛且深入,包括但不限于Android系统架构、进程间通信、安全机制等,学习和掌握它需要具备扎实的Android开发基础和对系统层面的深刻理解...
#### 线程基础与Thread类 线程是程序执行的最小单元,是进程中的单一顺序控制流。在OS层面,进程是资源分配的基本单位,而线程则作为调度的基本单位。在Android开发中,线程的使用主要通过Java的`Thread`类来实现。...
由于主线程的重要性,所有与UI相关的操作必须在此线程中执行,以确保界面的流畅性和响应性。 然而,Android应用中往往需要执行一些耗时的操作,如文件I/O、数据库操作和网络请求。这些任务如果在主线程中执行,会...
本篇文章将详细介绍Android线程的基础知识、使用方法及同步机制等内容。 #### 一、Android线程概述 在Android应用开发过程中,线程的应用非常广泛。线程作为进程中的执行单元,可以被用来处理一些耗时操作,如网络...
在Android系统中,组件是应用程序的基本构建块,主要包括Activity、Service、BroadcastReceiver和ContentProvider四种。本篇文章将深入探讨Android组件的复用机制以及它们与进程之间的关系。 首先,我们来了解一下...
同时,了解进程和线程管理、权限控制以及系统服务通信等基础知识也会对开发守护进程有极大帮助。此外,需要注意的是,尽管守护进程可以提高后台任务的持久性,但也可能导致电池消耗增加和系统资源占用,因此在实际...
线程与进程的理论知识入门2线程与进程的理论知识入门2
以上就是“Android-用于app模块初始化可区分进程线程并设置优先级”项目所涉及的主要技术点,理解并掌握这些知识点对于提升Android应用的性能和用户体验至关重要。开发者应根据应用需求,灵活运用这些策略来设计高效...
根据标题《android多线程高效编程》和描述内容,我们可以了解到本书将从基础层面介绍线程和进程的概念,这是Linux内核管理执行流的基本单位,也是Android操作系统多任务处理的核心。然后,书中重点在于介绍Android...
Android系统本身是基于Linux内核的,因此其多线程机制与传统的Linux多线程相似,但又有针对移动设备特性的优化。下面将详细讨论Android多线程的相关知识点。 1. **线程的基本概念**: - 线程是程序中的执行流,每...