大家注意看到有一些NO上添加了一些数字,其实这些从能力上来说是YES,但是为什么说是NO呢?下面一个一个解释:
数字1:启动Activity在这些类中是可以的,但是需要创建一个新的task。一般情况不推荐。
数字2:在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用。
数字3:在receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播的当前值。(可以无视)
注:ContentProvider、BroadcastReceiver之所以在上述表格中,是因为在其内部方法中都有一个context用于使用。
一个应用中Context的数量等于Activity的个数 + Service的个数 + 1,这个1为Application。
另外通过对service的应用,可以得出结论,一个apk,即一个应用(Application)可以跑在多个进程中,一个进程在一个虚拟机中运行,也即一个apk可以启动多个虚拟机。
通过shareuserID可以将多个apk,跑在同一个进程中。
从而得出结论:一个虚拟机只能跑一个进程,一个进程里可以跑多个应用,一个应用也可以跑在多个进程中,这就是他们的关系。
#4 Launch Modes 4 launch modes
android:allowTaskReparenting
用来标记Activity能否从启动的Task移动到有着affinity的Task(当这个Task进入到前台时)
“true”,表示能移动,“false”,表示它必须呆在启动时呆在的那个Task里。
如果这个特性没有被设定,设定到<application>元素上的allowTaskReparenting特性的值会应用到Activity上。默认值为“false”。
一般来说,当Activity启动后,它就与启动它的Task关联,并且在那里耗尽它的整个生命周期。当当前的Task不再显示时,你可以使用这个特性来强制Activity移动到有着affinity的Task中。典型用法是:把一个应用程序的Activity移到另一个应用程序的主Task中。
例如,如果 email中包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。这个Activity是由Browser应用程序定义的,但是,现在它作为email Task的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见,并且,当email Task再次进入前台时,就看不到它了。
Actvity的affinity是由taskAffinity特性定义的。Task的affinity是通过读取根Activity的affinity决定。因此,根Activity总是位于相同affinity的Task里。由于启动模式为“singleTask”和“singleInstance”的Activity只能位于Task的底部,因此,重新宿主只能限于“standard”和“singleTop”模式。
android:alwaysRetainTaskState
用来标记Activity所在的Task的状态是否总是由系统来保持。
“true”,表示总是;“false”,表示在某种情形下允许系统恢复Task到它的初始化状态。默认值是“false”。
这个特性只针对Task的根Activity有意义;对其它Activity来说,忽略之。
一般来说,特定的情形如当用户从主画面重新选择这个Task时,系统会对这个Task进行清理(从stack中删除位于根Activity之上的所有Activivity)。典型的情况,当用户有一段时间没有访问这个Task时也会这么做,例如30分钟。
然而,当这个特性设为“true”时,用户总是能回到这个Task的最新状态,无论他们是如何启动的。这非常有用,例如,像Browser应用程序,这里有很多的状态(例如多个打开的Tab),用户不想丢失这些状态。
android:clearTaskOnLaunch
用来标记是否从Task中清除所有的Activity,除了根Activity外(每当从主画面重新启动时)
“true”,表示总是清除至它的根Activity,“false”表示不。默认值是“false”。
这个特性只对启动一个新的Task的Activity(根Activity)有意义;对Task中其它的Activity忽略。
当这个值为“true”,每次用户重新启动这个Task时,都会进入到它的根Activity中,不管这个Task最后在做些什么,也不管用户是使用BACK还是HOME离开的。当这个值为“false”时,可能会在一些情形下(参考alwaysRetainTaskState特性)清除Task的Activity,但不总是。
假设,某人从主画面启动了Activity P,并从那里迁移至Activity Q。接下来用户按下HOME,然后返回Activity P。一般,用户可能见到的是Activity Q,因为它是P的Task中最后工作的内容。然而,如果P设定这个特性为“true”,当用户按下HOME并使这个Task再次进入前台时,其上的所有的Activity(在这里是Q)都将被清除。因此,当返回到这个Task时,用户只能看到P。
如果这个特性和allowTaskReparenting都设定为“true”,那些能重新宿主的Activity会移动到共享affinity的Task中;剩下的Activity都将被抛弃,如上所述。
android:finishOnTaskLaunch
用来标记当用户再次启动它的Task(在主画面选择这个Task)时已经存在的Activity实例是否要关闭(结束)
“true”,表示应该关闭,“false”表示不关闭。默认值是“false”。
如果这个特性和allowTaskReparenting都设定为“true”,这个特性胜出。Activity的affinity忽略。这个Activity不会重新宿主,但是会销毁。
android:launchMode
用于指示Activity如何启动。这里有四种模式,与Intent对象中的Activity Flags(FLAG_ACTIVITY_*变量)共同作用,来决定Activity如何启动来处理Intent。它们是:
"standard"
"singleTop"
"singleTask"
"singleInstance"
默认模式是“standard”。
前面文章:“Android四种Activity的加载模式”已经详细描述,这里就不做描述了.
android:noHistory
用于标记当用户从Activity上离开并且它在屏幕上不再可见时Activity是否从Activity stack中清除并结束(调用finish()方法)——“true”,表示它应该关闭,“false”,表示不需要。默认值是“false”。
“true”值意味着Activity不会留下历史痕迹。因为它不会在Activity stack的Task中保留,因此,用户不能返回它。
比如启用界面的就可以借用这个。
android:taskAffinity
这就是本文所描述的任务共用性。
Activity为Task拥有的一个affinity。拥有相同的affinity的Activity理论上属于相同的Task(在用户的角度是相同的“应用程序”)。Task的affinity是由它的根Activity决定的。
affinity决定两件事情——Activity重新宿主的Task(参考allowTaskReparenting特性)和使用FLAG_ACTIVITY_NEW_TASK标志启动的Activity宿主的Task。
默认情况,一个应用程序中的所有Activity都拥有相同的affinity。捏可以设定这个特性来重组它们,甚至可以把不同应用程序中定义的Activity放置到相同的Task中。为了明确Activity不宿主特定的Task,设定该特性为空的字符串。
如果这个特性没有设置,Activity将从应用程序的设定那里继承下来(参考<application>元素的taskAffinity特性)。应用程序默认的affinity的名字是<manifest>元素中设定的package名。
#X86 and ARM X86和ARM都是指CPU的内核。X86类型的处理器是典型的CISC,指令集丰富,性能强。我们目前在桌面电脑,笔记本电脑中使用的Intel、AMD处理器,就是X86处理器。ARM是一家英国的处理器设计公司,其设计的处理器采用了ARM内核。ARM处理器是典型的RISC,指令集较X86要精简很多,串行性能要远远弱于X86。但ARM指令集少,电路规模小,功耗低,发热低,非常适合于嵌入式、便携式电子产品,如手机、平板,以及工业嵌入式等。
#JNI
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java 虚拟机环境下。
#Android
android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。 蓝色的代表java程序,黄色的代码为运行JAVA程序而实现的虚拟机,绿色部分为C/C++语言编写的程序库,红色的代码内核(linux内核+driver)。在Application Framework之下,由C/C++的程序库组成,通过JNI完成从JAVA到C的调用。
-
应用程序 所有的应用程序都是使用JAVA语言编写的,每一个应用程序由一个或者多个活动组成,活动必须以Activity类为超类,活动类似于操作系统上的进程,但是活动比操作系统的进程要更为灵活,与进程类似的是,活动在多种状态之间进行切换。 利用JAVA的跨平台性质,基于Android框架开发的应用程序可以不用编译运行于任何一台安装有android系统的平台,这点正是Android的精髓所在。
-
应用程序框架 应用程序的架构设计简化了组件的重用;任何一个应用程序都可以发布它的功能块并且任何其它的应用程序都可以使用其所发布的功能块(不过得遵循框架的安全性限制)。帮助程序员快速的开发程序,并且该应用程序重用机制也使用户可以方便的替换程序组件。 隐藏在每个应用后面的是一系列的服务和系统, 其中包括; a.丰富而又可扩展的视图(Views),可以用来构建应用程序, 它包括列表(lists),网格(grids),文本框(text boxes),按钮(buttons), 甚至可嵌入的web浏览器。 b.内容提供器(Content Providers)使得应用程序可以访问另一个应用程序的数据(如联系人数据库), 或者共享它们自己的数据。 c.资源管理器(Resource Manager)提供非代码资源的访问,如本地字符串,图形,和布局文件(layout files)。 d.通知管理器(Notification Manager)使得应用程序可以在状态栏中显示自定义的提示信息。 e.活动管理器(Activity Manager)用来管理应用程序生命周期并提供常用的导航回退功能。
-
系统运行库 a)程序库 Android包含一些C/C++库,这些库能被Android系统中不同的组件使用。它们通过Android应用程序框架为开发者提供服务。 以下是一些核心库: 主要包括基本的C库、以及多媒体库以支持各种多媒体格式、位图和矢量字体、2D和3D图形引擎、浏览器、数据库支持。 1.Bionic系统C库。 2.媒体库,基于PacketVideo OpenCORE。 3.Surface Manager 顾名思义,用于管理Surface。 4.Webkit,LibWebCore 浏览器,基于Webkit引擎。 5.SGL 底层的2D图形引擎 6.3D libraries 基于OpenGL ES 1.0 APIs实现 7.FreeType 位图(bitmap)和矢量(vector)字体显示。 8.SQLite 一个对于所有应用程序可用,功能强劲的轻型关系型数据库引擎。
另外这里还有一个硬件抽象层。其实Android并非所有的设备驱动都放在linux内核里面,有一部分实现在用户空间, 这么做的主要原因是可以避开Linux所遵循的GPL协议,一般情况下如果要将Android移植到其他硬件去运行, 只需要实现这部分代码即可。包括:显示器驱动,声音,相机,GPS,GSM等等。
b)Android 运行库
Android 包括了一个核心库,该核心库提供了JAVA编程语言核心库的大多数功能。
每一个 Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例。
Dalvik被设计成一个设备可以同时高效地运行多个虚拟系统。
Dalvik虚拟机执行(.dex)的Dalvik可执行文件,该格式文件针对小内存使用做了优化。
同时虚拟机是基于寄存器的,所有的类都经由JAVA编译器编译,然后通过SDK中的 "dx" 工具转化成.dex格式由虚拟机执行。
Dalvik虚拟机依赖于linux内核的一些功能,比如线程机制和底层内存管理机制。
- Linux 内核
Android 的核心系统服务依赖于 Linux 2.6 内核 ,如安全性,内存管理,进程管理, 网络协议栈和驱动模型。
Linux 内核也同时作为硬件和软件栈之间的抽象层。其外还对其做了部分修改,主要涉及两部分修改:
a)Binder
(IPC):提供有效的进程间通信,虽然linux内核本身已经提供了这些功能,但Android系统很多服务都需要用到该功能,为了某种原因 其实现了自己的一套。 b)电源管理:为手持设备节省能耗。
#Handler A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
Scheduling messages is accomplished with the post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler's handleMessage(Message) method (requiring that you implement a subclass of Handler).
When posting or sending to a Handler, you can either allow the item to be processed as soon as the message queue is ready to do so, or specify a delay before it gets processed or absolute time for it to be processed. The latter two allow you to implement timeouts, ticks, and other timing-based behavior.
When a process is created for your application, its main thread is dedicated to running a message queue that takes care of managing the top-level application objects (activities, broadcast receivers, etc) and any windows they create. You can create your own threads, and communicate back with the main application thread through a Handler. This is done by calling the same post or sendMessage methods as before, but from your new thread. The given Runnable or Message will then be scheduled in the Handler's message queue and processed when appropriate.
这样基本就将Handler的创建过程完全搞明白了,总结一下就是在主线程中可以直接创建Handler对象,而在子线程中需要先调用Looper.prepare()才能创建Handler对象。
(Handle机制)[http://blog.csdn.net/guolin_blog/article/details/9991569]
The Handler class can be used to register to a thread and provides a simple channel to send data to this thread.
A Handler object registers itself with the thread in which it is created. For example, if you create a new instance of the Handler class in the onCreate() method of your activity, the resulting Handler object can be used to post data to the main thread.
The data which can be posted via the Handler class can be an instance of the Message or the Runnable class.
#JAVA Thread Pool JAVA线程池
AsyncTask
When an asynchronous task is executed, the task goes through 4 steps:
- onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
- doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
- onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
- onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
#Differences between AsyncTask and Thread
For long-running or CPU-intensive tasks, there are basically two ways to do this: Java threads, and Android's native AsyncTask.
Neither one is necessarily better than the other, but knowing when to use each call is essential to leveraging the system's performance to your benefit.
Use AsyncTask for:
Simple network operations which do not require downloading a lot of data Disk-bound tasks that might take more than a few milliseconds Use Java threads for:
Network operations which involve moderate to large amounts of data (either uploading or downloading) High-CPU tasks which need to be run in the background Any task where you want to control the CPU usage relative to the GUI thread
The AsyncTask does not handle configuration changes automatically, i.e. if the activity is recreated, the programmer has to handle that in his coding.
A common solution to this is to declare the AsyncTask in a retained headless fragment.
#多图加载例子 多图加载例子
#When GC JVM进行次GC的频率很高,但因为这种GC占用时间极短,所以对系统产生的影响不大。更值得关注的是主GC的触发条件,因为它对系统影响很明显。总的来说,有两个条件会触发主GC:
①当应用程序空闲时,即没有应用线程在运行时,GC会被调用。因为GC在优先级最低的线程中进行,所以当应用忙时,GC线程就不会被调用,但以下条件除外。
②Java堆内存不足时,GC会被调用。当应用线程在运行,并在运行过程中创建新对象,若这时内存空间不足,JVM就会强制地调用GC线程,以便回收内存用于新的分配。若GC一次之后仍不能满足内存分配的要求,JVM会再进行两次GC作进一步的尝试,若仍无法满足要求,则 JVM将报“out of memory”的错误,Java应用将停止。
由于是否进行主GC由JVM根据系统环境决定,而系统环境在不断的变化当中,所以主GC的运行具有不确定性,无法预计它何时必然出现,但可以确定的是对一个长期运行的应用来说,其主GC是反复进行的。
(String, StringBuffer and StringBuilder)[http://www.cnblogs.com/fancydeepin/archive/2013/04/23/min-snail-speak_String-StringBuffer-StringBuilder.html]
The reason everyone always says to avoid System.gc() is that it is a pretty good indicator of fundamentally broken code. Any code that depends on it for correctness is certainly broken; any that rely on it for performance are most likely broken.
You don't know what sort of garbage collector you are running under. There are certainly some that do not "stop the world" as you assert, but some JVMs aren't that smart or for various reasons (perhaps they are on a phone?) don't do it. You don't know what it's going to do.
Also, it's not guaranteed to do anything. The JVM may just entirely ignore your request.
The combination of "you don't know what it will do," "you don't know if it will even help," and "you shouldn't need to call it anyway" are why people are so forceful in saying that generally you shouldn't call it. I think it's a case of "if you need to ask whether you should be using this, you shouldn't"
Some time ago I was interviewing candidates for a Senior Java Engineer position. Among the many questions I asked was "What can you tell me about weak references?" I wasn't expecting a detailed technical treatise on the subject. I would probably have been satisfied with "Umm... don't they have something to do with garbage collection?" I was instead surprised to find that out of twenty-odd engineers, all of whom had at least five years of Java experience and good qualifications, only two of them even knew that weak references existed, and only one of those two had actual useful knowledge about them. I even explained a bit about them, to see if I got an "Oh yeah" from anybody -- nope. I'm not sure why this knowledge is (evidently) uncommon, as weak references are a massively useful feature which have been around since Java 1.2 was released, over seven years ago. Now, I'm not suggesting you need to be a weak reference expert to qualify as a decent Java engineer. But I humbly submit that you should at least know what they are -- otherwise how will you know when you should be using them? Since they seem to be a little-known feature, here is a brief overview of what weak references are, how to use them, and when to use them. Strong references First I need to start with a refresher on strong references. A strong reference is an ordinary Java reference, the kind you use every day. For example, the code: StringBuffer buffer = new StringBuffer();
creates a new StringBuffer() and stores a strong reference to it in the variable buffer. Yes, yes, this is kiddie stuff, but bear with me. The important part about strong references -- the part that makes them "strong" -- is how they interact with the garbage collector. Specifically, if an object is reachable via a chain of strong references (strongly reachable), it is not eligible for garbage collection. As you don't want the garbage collector destroying objects you're working on, this is normally exactly what you want. When strong references are too strong It's not uncommon for an application to use classes that it can't reasonably extend. The class might simply be markedfinal, or it could be something more complicated, such as an interface returned by a factory method backed by an unknown (and possibly even unknowable) number of concrete implementations. Suppose you have to use a class Widget and, for whatever reason, it isn't possible or practical to extendWidget to add new functionality. What happens when you need to keep track of extra information about the object? In this case, suppose we find ourselves needing to keep track of each Widget's serial number, but theWidget class doesn't actually have a serial number property -- and because Widget isn't extensible, we can't add one. No problem at all, that's what HashMapsare for: serialNumberMap.put(widget, widgetSerialNumber);
This might look okay on the surface, but the strong reference towidget will almost certainly cause problems. We have to know (with 100% certainty) when a particularWidget's serial number is no longer needed, so we can remove its entry from the map. Otherwise we're going to have a memory leak (if we don't remove Widgets when we should) or we're going to inexplicably find ourselves missing serial numbers (if we remove Widgets that we're still using). If these problems sound familiar, they should: they are exactly the problems that users of non-garbage-collected languages face when trying to manage memory, and we're not supposed to have to worry about this in a more civilized language like Java. Another common problem with strong references is caching, particular with very large structures like images. Suppose you have an application which has to work with user-supplied images, like the web site design tool I work on. Naturally you want to cache these images, because loading them from disk is very expensive and you want to avoid the possibility of having two copies of the (potentially gigantic) image in memory at once. Because an image cache is supposed to prevent us from reloading images when we don't absolutely need to, you will quickly realize that the cache should always contain a reference to any image which is already in memory. With ordinary strong references, though, that reference itself will force the image to remain in memory, which requires you (just as above) to somehow determine when the image is no longer needed in memory and remove it from the cache, so that it becomes eligible for garbage collection. Once again you are forced to duplicate the behavior of the garbage collector and manually determine whether or not an object should be in memory. Weak references A weak reference, simply put, is a reference that isn't strong enough to force an object to remain in memory. Weak references allow you to leverage the garbage collector's ability to determine reachability for you, so you don't have to do it yourself. You create a weak reference like this: WeakReference weakWidget = new WeakReference(widget);
and then elsewhere in the code you can useweakWidget.get() to get the actual Widgetobject. Of course the weak reference isn't strong enough to prevent garbage collection, so you may find (if there are no strong references to the widget) that weakWidget.get()suddenly starts returning null. To solve the "widget serial number" problem above, the easiest thing to do is use the built-in WeakHashMap class.WeakHashMap works exactly like HashMap, except that the keys (not the values!) are referred to using weak references. If a WeakHashMap key becomes garbage, its entry is removed automatically. This avoids the pitfalls I described and requires no changes other than the switch fromHashMap to a WeakHashMap. If you're following the standard convention of referring to your maps via theMap interface, no other code needs to even be aware of the change. Reference queues Once a WeakReference starts returningnull, the object it pointed to has become garbage and the WeakReference object is pretty much useless. This generally means that some sort of cleanup is required;WeakHashMap, for example, has to remove such defunct entries to avoid holding onto an ever-increasing number of deadWeakReferences. The ReferenceQueue class makes it easy to keep track of dead references. If you pass a ReferenceQueueinto a weak reference's constructor, the reference object will be automatically inserted into the reference queue when the object to which it pointed becomes garbage. You can then, at some regular interval, process the ReferenceQueue and perform whatever cleanup is needed for dead references. Different degrees of weakness Up to this point I've just been referring to "weak references", but there are actually four different degrees of reference strength: strong, soft, weak, and phantom, in order from strongest to weakest. We've already discussed strong and weak references, so let's take a look at the other two. Soft references A soft reference is exactly like a weak reference, except that it is less eager to throw away the object to which it refers. An object which is only weakly reachable (the strongest references to it are WeakReferences) will be discarded at the next garbage collection cycle, but an object which is softly reachable will generally stick around for a while. SoftReferences aren't required to behave any differently than WeakReferences, but in practice softly reachable objects are generally retained as long as memory is in plentiful supply. This makes them an excellent foundation for a cache, such as the image cache described above, since you can let the garbage collector worry about both how reachable the objects are (a strongly reachable object will never be removed from the cache) and how badly it needs the memory they are consuming. Phantom references A phantom reference is quite different than eitherSoftReference or WeakReference. Its grip on its object is so tenuous that you can't even retrieve the object -- its get() method always returns null. The only use for such a reference is keeping track of when it gets enqueued into a ReferenceQueue, as at that point you know the object to which it pointed is dead. How is that different from WeakReference, though? The difference is in exactly when the enqueuing happens.WeakReferences are enqueued as soon as the object to which they point becomes weakly reachable. This is beforefinalization or garbage collection has actually happened; in theory the object could even be "resurrected" by an unorthodoxfinalize() method, but the WeakReferencewould remain dead. PhantomReferences are enqueued only when the object is physically removed from memory, and theget() method always returns nullspecifically to prevent you from being able to "resurrect" an almost-dead object. What good are PhantomReferences? I'm only aware of two serious cases for them: first, they allow you to determine exactly when an object was removed from memory. They are in fact the only way to determine that. This isn't generally that useful, but might come in handy in certain very specific circumstances like manipulating large images: if you know for sure that an image should be garbage collected, you can wait until it actually is before attempting to load the next image, and therefore make the dreaded OutOfMemoryError less likely. Second, PhantomReferences avoid a fundamental problem with finalization: finalize() methods can "resurrect" objects by creating new strong references to them. So what, you say? Well, the problem is that an object which overridesfinalize() must now be determined to be garbage in at least two separate garbage collection cycles in order to be collected. When the first cycle determines that it is garbage, it becomes eligible for finalization. Because of the (slim, but unfortunately real) possibility that the object was "resurrected" during finalization, the garbage collector has to run again before the object can actually be removed. And because finalization might not have happened in a timely fashion, an arbitrary number of garbage collection cycles might have happened while the object was waiting for finalization. This can mean serious delays in actually cleaning up garbage objects, and is why you can getOutOfMemoryErrors even when most of the heap is garbage. With PhantomReference, this situation is impossible -- when a PhantomReference is enqueued, there is absolutely no way to get a pointer to the now-dead object (which is good, because it isn't in memory any longer). BecausePhantomReference cannot be used to resurrect an object, the object can be instantly cleaned up during the first garbage collection cycle in which it is found to be phantomly reachable. You can then dispose whatever resources you need to at your convenience. Arguably, the finalize() method should never have been provided in the first place. PhantomReferencesare definitely safer and more efficient to use, and eliminatingfinalize() would have made parts of the VM considerably simpler. But, they're also more work to implement, so I confess to still using finalize() most of the time. The good news is that at least you have a choice. Conclusion I'm sure some of you are grumbling by now, as I'm talking about an API which is nearly a decade old and haven't said anything which hasn't been said before. While that's certainly true, in my experience many Java programmers really don't know very much (if anything) about weak references, and I felt that a refresher course was needed. Hopefully you at least learned a littlesomething from this review.
#对Bitmap的内存管理 1.及时的销毁。
虽然,系统能够确认Bitmap分配的内存最终会被销毁,但是由于它占用的内存过多,所以很可能会超过Java堆的限制。因此,在用完Bitmap时,要及时的recycle掉。recycle并不能确定立即就会将Bitmap释放掉,但是会给虚拟机一个暗示:“该图片可以释放了”。
2.设置一定的采样率。
有时候,我们要显示的区域很小,没有必要将整个图片都加载出来,而只需要记载一个缩小过的图片,这时候可以设置一定的采样率,那么就可以大大减小占用的内存。如下面的代码:
private ImageView preview;
BitmapFactory.Options options = newBitmapFactory.Options();
//图片宽高都为原来的二分之一,即图片为原来的四分之一
options.inSampleSize = 2;
Bitmap bitmap =BitmapFactory.decodeStream(cr.openInputStream(uri), null, options);
preview.setImageBitmap(bitmap);
3.巧妙的运用软引用(SoftRefrence)
有些时候,我们使用Bitmap后没有保留对它的引用,因此就无法调用Recycle函数。这时候巧妙的运用软引用,可以使Bitmap在内存快不足时得到有效的释放。如下:
SoftReference<Bitmap> bitmap_ref
= new SoftReference<Bitmap>(BitmapFactory.decodeStream(inputstream));
……
……
if (bitmap_ref .get() != null)
bitmap_ref.get().recycle();
dvm的进程和Linux的进程, 应用程序的进程为同一个概念
#SIM卡的文件系统 SIM卡里的所有文件按树来组织:
- 主文件MF(Master File)——每一块SIM卡只有一个唯一的主文件,其他所有文件都是它的子孙,主文件只有文件头,里面存放着整个SIM卡的控制和管理信息
- 专用文件DF(Dedicated File)——也是只有一个文件头, 里面存放着整个目录的管理控制信息, 专用文件相当于一个目录的根.
- 基本文件EF(Elementary File)——既有文件头,也有文件体, 文件头存放该文件的位置和控制信息, 文件体存放真正的数据,
整个SIM卡中只有基本文件有文件体, 也只有基本文件才用来存放数据.
#嵌入式实时操作系统 当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协调一致运行的嵌入式操作系统。 注:在工业控制、 军事设备、 航空航天等领域对系统的响应时间有苛刻的要求,这就需要使用实时系统。我们常常说的嵌入式操作系统都是嵌入式实时操作系统。比如μC/OS-II、eCOS和Linux、HOPEN OS。故对嵌入式实时操作系统的理解应该建立在对嵌入式系统的理解之上加入对响应时间的要求。
#Animation android动画分三类:
- View 动画,又叫Tween动画
- 是frame 动画(帧动画),又叫drawable 动画
- 属性动画,即property animation.