技术改变世界 阅读塑造人生! - shaogx.com

This string was altered by TechBlog\Plugins\Example.; This is an example to show the potential of an offcanvas layout pattern in Bootstrap. Try some responsive-range viewport sizes to see it in action.

Android 内存优化的几点知识

不少人认为JAVA程序,因为有垃圾回收机制,应该没有内存泄露。其实如果我们一个程序中,已经不再使用某个对象,但是因为仍然有引用指向它,垃圾回收器就无法回收它,当然该对象占用的内存就无法被使用,这就造成了内存泄露。如果我们的java运行很久,而这种内存泄露不断的发生,最后就没内存可用了。当然java的,内存泄漏和C/C++是不一样的。如果java程序完全结束后,它所有的对象就都不可达了,系统就可以对他们进行垃圾回收,它的内存泄露仅仅限于它本身,而不会影响整个系统的。C/C++的内存泄露就比较糟糕了,它的内存泄露是系统级,即使该C/C++程序退出,它的泄露的内存也无法被系统回收,永远不可用了,除非重启机器。 Android的一个应用程序的内存泄露对别的应用程序影响不大。为了能够使得Android应用程序安全且快速的运行,Android的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行,它是由Zygote服务进程孵化出来的,也就是说每个应用程序都是在属于自己的进程中运行的。Android为不同类型的进程分配了不同的内存使用上限,如果程序在运行过程中出现了内存泄漏的而造成应用进程使用的内存超过了这个上限,则会被系统视为内存泄漏,从而被kill掉,这使得仅仅自己的进程被kill掉,而不会影响其他进程(如果是system_process等系统进程出问题的话,则会引起系统重启)。 一、引用没释放造成的内存泄露 1.1注册没取消造成的内存泄露 这种Android的内存泄露比纯java的内存泄露还要严重,因为其他一些Android程序可能引用我们的Anroid程序的对象(比如注册机制)。即使我们的Android程序已经结束了,但是别的引用程序仍然还有对我们的Android程序的某个对象的引用,泄露的内存依然不能被垃圾回收。 比如示例1: 假设我们希望在锁屏界面(LockScreen)中,监听系统中的电话服务以获取一些信息(如信号强度等),则可以在LockScreen中定义一个PhoneStateListener的对象,同时将它注册到TelephonyManager服务中。对于LockScreen对象,当需要显示锁屏界面的时候就会创建一个LockScreen对象,而当锁屏界面消失的时候LockScreen对象就会被释放掉。 但是如果在释放LockScreen对象的时候忘记取消我们之前注册的PhoneStateListener对象,则会导致LockScreen无法被垃圾回收。如果不断的使锁屏界面显示和消失,则最终会由于大量的LockScreen对象没有办法被回收而引起OutOfMemory,使得system_process进程挂掉。 虽然有些系统程序,它本身好像是可以自动取消注册的(当然不及时),但是我们还是应该在我们的程序中明确的取消注册,程序结束时应该把所有的注册都取消掉。 1.2集合中对象没清理造成的内存泄露 我们通常把一些对象的引用加入到了集合中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大。如果这个集合是static的话,那情况就更严重了。 二、资源对象没关闭造成的内存泄露 资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,我们在不使用的时候,应该及时关闭它们,以便它们的缓冲及时回收内存。它们的缓冲不仅存在于java虚拟机内,还存在于java虚拟机外。如果我们仅仅是把它的引用设置为null,而不关闭它们,往往会造成内存泄露。因为有些资源性对象,比如SQLiteCursor(在析构函数finalize(),如果我们没有关闭它,它自己会调close()关闭),如果我们没有关闭它,系统在回收它时也会关闭它,但是这样的效率太低了。因此对于资源性对象在不使用的时候,应该调用它的close()函数,将其关闭掉,然后才置为null.在我们的程序退出时一定要确保我们的资源性对象已经关闭。 程序中经常会进行查询数据库的操作,但是经常会有使用完毕Cursor后没有关闭的情况。如果我们的查询结果集比较小,对内存的消耗不容易被发现,只有在常时间大量操作的情况下才会复现内存问题,这样就会给以后的测试和问题排查带来困难和风险。 三、一些不良代码成内存压力 有些代码并不造成内存泄露,但是它们,或是对没使用的内存没进行有效及时的释放,或是没有有效的利用已有的对象而是频繁的申请新内存,对内存的回收和分配造成很大影响的,容易迫使虚拟机不得不给该应用进程分配更多的内存,造成不必要的内存开支。 3.1,Bitmap没调用recycle() Bitmap对象在不使用时,我们应该先调用recycle()释放内存,然后才它设置为null.虽然recycle()从源码上看,调用它应该能立即释放Bitmap的主要内存,但是测试结果显示它并没能立即释放内存。但是我它应该还是能大大的加速Bitmap的主要内存的释放。 3.2,构造Adapter时,没有使用缓存的 convertView 以构造ListView的BaseAdapter为例,在BaseAdapter中提共了方法: public View getView(int position, View convertView, ViewGroup parent)来向ListView提供每一个item所需要的view对象。初始时ListView会从BaseAdapter中根据当前的屏幕布局实例化一定数量的view对象,同时ListView会将这些view对象缓存起来。当向上滚动ListView时,原先位于最上面的list item的view对象会被回收,然后被用来构造新出现的最下面的list item。这个构造过程就是由getView()方法完成的,getView()的第二个形参 View convertView就是被缓存起来的list item的view对象(初始化时缓存中没有view对象则convertView是null)。 由此可以看出,如果我们不去使用convertView,而是每次都在getView()中重新实例化一个View对象的话,即浪费时间,也造成内存垃圾,给垃圾回收增加压力,如果垃圾回收来不及的话,虚拟机将不得不给该应用进程分配更多的内存,造成不必要的内存开支。ListView回收list item的view对象的过程可以查看: view plaincopy to clipboardprint? android.widget.AbsListView.java --> void addScrapView(View scrap) 方法。 示例代码:public View getView(int position, View convertView, ViewGroup parent) { View view = new Xxx(...); ... ... return view; } 修正示例代码:public View getView(int position, View convertView, ViewGroup parent) { View view = null; if (convertView != null) { view = convertView; populate(view, getItem(position)); ... } else { view = new Xxx(...); ... } return view; } view plaincopyprint? android.widget.AbsListView.java --> void addScrapView(View scrap) 方法。 示例代码:public View getView(int position, View convertView, ViewGroup parent) { View view = new Xxx(...); ... ... return view; } 修正示例代码:public View getView(int position, View convertView, ViewGroup parent) { View view = null; if (convertView != null) { view = convertView; populate(view, getItem(position)); ... } else { view = new Xxx(...); ... } return view; } Android内存管理 概述 在android的开发中,要时刻主要内存的分配和垃圾回收,因为系统为每一个dalvik虚拟机分配的内存是有限的,在google的G1中,分配的最大堆大小只有16M,后来的机器一般都为24M,实在是少的可怜。这样就需要我们在开发过程中要时刻注意。不要因为自己的代码问题而造成OOM错误。 JAVA的内存管理 大家都知道,android应用层是由java开发的,android的davlik虚拟机与jvm也类似,只不过它是基于寄存器的。因此要了解android的内存管理就必须得了解java的内存分配和垃圾回收机制。 在java中,是通过new关键字来为对象分配内存的,而内存的释放是由垃圾收集器(GC)来回收的,工程师在开发的过程中,不需要显式的去管理内存。但是这样有可能在不知不觉中就会浪费了很多内存,最终导致java虚拟机花费很多时间去进行垃圾回收,更严重的是造成JVM的OOM。因此,java工程师还是有必要了解JAVA的内存分配和垃圾回收机制。内存结构 file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-6926.png 上面这张图是JVM的结构图,它主要四个部分组成:Class Loader子系统和执行引擎,运行时方法区和本地方法区,我们主要来看下RUNTIME DATA AREA区,也就是我们常说的JVM内存。从图中可以看出,RUNTIMEDATA AREA区主要由5个部分组成: · Method Area:被装载的class的元信息存储在Method Area中,它是线程共享的 · Heap(堆):一个java虚拟机实例中只存在一个堆空间,存放一些对象信息,它是线程共享的 · Java栈: java虚拟机直接对java栈进行两种操作,以帧为单位的压栈和出栈(非线程共享) · 程序计数器(非线程共享) · 本地方法栈(非线程共享) JVM的垃圾回收(GC) file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-12485.png JVM的垃圾原理是这样的,它把对象分为年轻代(Young)、年老代(Tenured)、持久代(Perm),对不同生命周期的对象使用不同的垃圾回收算法。 · 年轻代(Young) 年轻代分为三个区,一个eden区,两个Survivor区。程序中生成的大部分新的对象都在Eden区中,当Eden区满时,还存活的对象将被复制到其中一个Survivor区,当此Survivor区的对象占用空间满了时,此区存活的对象又被复制到另外一个Survivor区,当这个Survivor区也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制到年老代。 · 年老代(Tenured) 年老代存放的是上面年轻代复制过来的对象,也就是在年轻代中还存活的对象,并且区满了复制过来的。一般来说,年老代中的对象生命周期都比较长。 · 持久代(Perm) 用于存放静态的类和方法,持久代对垃圾回收没有显著的影响。 Android中内存泄露监测 在了解了JVM的内存管理后,我们再回过头来看看,在android中应该怎样来监测内存,从而看在应用中是否存在内存分配和垃圾回收问题而造成内存泄露情况。 在android中,有一个相对来说还不错的工具,可以用来监测内存是否存在泄露情况:DDMS—Heap file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-22715.png 使用方法比较简单: · 选择DDMS视图,并打开Devices视图和Heap视图 · 点击选择要监控的进程,比如:上图中我选择的是system_process · 选中Devices视图界面上的"update heap" 图标 · 点击Heap视图中的"Cause GC" 按钮(相当于向虚拟机发送了一次GC请求的操作) 在Heap视图中选择想要监控的Type,一般我们会观察dataobject的 total size的变化,正常情况下total size的值会稳定在一个有限的范围内,也就说程序中的代码良好,没有造成程序中的对象不被回收的情况。如果代码中存在没有释放对象引用的情况,那么data object的total size在每次GC之后都不会有明显的回落,随着操作次数的增加而total size也在不断的增加。(说明:选择好data object后,不断的操作应用,这样才可以看出total size的变化)。如果totalsize确实是在不断增加而没有回落,说明程序中有没有被释放的资源引用。那么我们应该怎么来定位呢? Android中内存泄露定位 Mat(memory analyzer tools)是我们常用的用来定位内存泄露的工具,如果你使用ADT,并且安装了MAT的eclipse插件,你需要做的是进入DDMS视图的Devices视图: file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-2165.png 点击"dump HPROF file"按钮,然后使用MAT分析下载下来的文件。 file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-6565.png 下面列出了存在的问题,点击detail进去,会列出详细的,可能会存在问题的代码: file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-32625.png file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-21158.png 关于MAT的使用可以参考:http://www.blogjava.net/rosen/ ... .html这位兄弟写的比较详细。总结不管是java还是android,都应该了解内存分配和垃圾回收机制,工程师要做到写的代码中没有bad code很难,关键是在出现问题的时候该怎么去排查 Android内存优化 一、 Android的内存机制 Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似。程序员通过new为对象分配内存,所有对象在java堆内分配空间;然而对象的释放是由垃圾回收器来完成的。C/C++中的内存机制是“谁污染,谁治理”,java的就比较人性化了,给我们请了一个专门的清洁工(GC)。 那么GC怎么能够确认某一个对象是不是已经被废弃了呢?Java采用了有向图的原理。Java将引用关系考虑为图的有向边,有向边从引用者指向引用对象。线程对象可以作为有向图的起始顶点,该图就是从起始顶点开始的一棵树,根顶点可以到达的对象都是有效对象,GC不会回收这些对象。如果某个对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被GC回收。 二、Android的内存溢出 Android的内存溢出是如何发生的? Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的机器为24M。因此我们所能利用的内存空间是有限的。如果我们的内存占用超过了一定的水平就会出现OutOfMemory的错误。 为什么会出现内存不够用的情况呢?我想原因主要有两个: · 由于我们程序的失误,长期保持某些资源(如Context)的引用,造成内存泄露,资源造成得不到释放。 · 保存了多个耗用内存过大的对象(如Bitmap),造成内存超出限制。 三、万恶的static static是Java中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例(Context的情况最多),这时就要谨慎对待了。public class ClassName { private static Context mContext; //省略 } 以上的代码是很危险的,如果将Activity赋值到么mContext的话。那么即使该Activity已经onDestroy,但是由于仍有对象保存它的引用,因此该Activity依然不会被释放。 我们举Android文档中的一个例子。private static Drawable sBackground; @Override protected void onCreate(Bundle state) { super.onCreate(state); TextView label = new TextView(this); label.setText("Leaks are bad"); if (sBackground == null) { sBackground = getDrawable(R.drawable.large_bitmap); } label.setBackgroundDrawable(sBackground); setContentView(label); } sBackground, 是一个静态的变量,但是我们发现,我们并没有显式的保存Contex的引用,但是,当Drawable与View连接之后,Drawable就将View设置为一个回调,由于View中是包含Context的引用的,所以,实际上我们依然保存了Context的引用。这个引用链如下: Drawable->TextView->Context 所以,最终该Context也没有得到释放,发生了内存泄露。 如何才能有效的避免这种引用的发生呢? 第一,应该尽量避免static成员变量引用资源耗费过多的实例,比如Context。 第二、Context尽量使用Application Context,因为Application的Context的生命周期比较长,引用它不会出现内存泄露的问题。 第三、使用WeakReference代替强引用。比如可以使用WeakReference mContextRef; 该部分的详细内容也可以参考Android文档中Article部分。 四、都是线程惹的祸 线程也是造成内存泄露的一个重要的源头。线程产生内存泄露的主要原因在于线程生命周期的不可控。我们来考虑下面一段代码。public class MyActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); new MyThread().start(); } private class MyThread extends Thread{ @Override public void run() { super.run(); //do somthing } } } 这段代码很平常也很简单,是我们经常使用的形式。我们思考一个问题:假设MyThread的run函数是一个很费时的操作,当我们开启该线程后,将设备的横屏变为了竖屏,一般情况下当屏幕转换时会重新创建Activity,按照我们的想法,老的Activity应该会被销毁才对,然而事实上并非如此。 由于我们的线程是Activity的内部类,所以MyThread中保存了Activity的一个引用,当MyThread的run函数没有结束时,MyThread是不会被销毁的,因此它所引用的老的Activity也不会被销毁,因此就出现了内存泄露的问题。 file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-6439.png 有些人喜欢用Android提供的AsyncTask,但事实上AsyncTask的问题更加严重,Thread只有在run函数不结束时才出现这种内存泄露问题,然而AsyncTask内部的实现机制是运用了ThreadPoolExcutor,该类产生的Thread对象的生命周期是不确定的,是应用程序无法控制的,因此如果AsyncTask作为Activity的内部类,就更容易出现内存泄露的问题。 这种线程导致的内存泄露问题应该如何解决呢? 第一、将线程的内部类,改为静态内部类。 第二、在线程内部采用弱引用保存Context引用。 解决的模型如下:public abstract class WeakAsyncTask extends AsyncTask { protected WeakReference mTarget; public WeakAsyncTask(WeakTarget target) { mTarget = new WeakReference(target); } @Override protected final void onPreExecute() { final WeakTarget target = mTarget.get(); if (target != null) { this.onPreExecute(target); } } @Override protected final Result doInBackground(Params... params) { final WeakTarget target = mTarget.get(); if (target != null) { return this.doInBackground(target, params); } else { return null; } } @Override protected final void onPostExecute(Result result) { final WeakTarget target = mTarget.get(); if (target != null) { this.onPostExecute(target, result); } } protected void onPreExecute(WeakTarget target) { // No default action } protected abstract Result doInBackground(WeakTarget target, Params... params); protected void onPostExecute(WeakTarget target, Result result) { // No default action } } 事实上,线程的问题并不仅仅在于内存泄露,还会带来一些灾难性的问题。由于本文讨论的是内存问题,所以在此不做讨论。 由于51cto不让我一次传完,说我的字数太多了,所以分开传了。 五、超级大胖子Bitmap 可以说出现OutOfMemory问题的绝大多数人,都是因为Bitmap的问题。因为Bitmap占用的内存实在是太多了,它是一个“超级大胖子”,特别是分辨率大的图片,如果要显示多张那问题就更显著了。 如何解决Bitmap带给我们的内存问题? 第一、及时的销毁。 虽然,系统能够确认Bitmap分配的内存最终会被销毁,但是由于它占用的内存过多,所以很可能会超过java堆的限制。因此,在用完Bitmap时,要及时的recycle掉。recycle并不能确定立即就会将Bitmap释放掉,但是会给虚拟机一个暗示:“该图片可以释放了”。 第二、设置一定的采样率。 有时候,我们要显示的区域很小,没有必要将整个图片都加载出来,而只需要记载一个缩小过的图片,这时候可以设置一定的采样率,那么就可以大大减小占用的内存。如下面的代码: private ImageView preview; BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一 Bitmap bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri), null, options); preview.setImageBitmap(bitmap); 第三、巧妙的运用软引用(SoftRefrence) 有些时候,我们使用Bitmap后没有保留对它的引用,因此就无法调用Recycle函数。这时候巧妙的运用软引用,可以使Bitmap在内存快不足时得到有效的释放。如下例:private class MyAdapter extends BaseAdapter { private ArrayList> mBitmapRefs = new ArrayList>(); private ArrayList mValues; private Context mContext; private LayoutInflater mInflater; MyAdapter(Context context, ArrayList values) { mContext = context; mValues = values; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } public int getCount() { return mValues.size(); } public Object getItem(int i) { return mValues.get(i); } public long getItemId(int i) { return i; } public View getView(int i, View view, ViewGroup viewGroup) { View newView = null; if(view != null) { newView = view; } else { newView =(View)mInflater.inflate(R.layout.image_view, false); } Bitmap bitmap = BitmapFactory.decodeFile(mValues.get(i).fileName); mBitmapRefs.add(new SoftReference(bitmap)); //此处加入ArrayList ((ImageView)newView).setImageBitmap(bitmap); return newView; } } 六、行踪诡异的Cursor Cursor是Android查询数据后得到的一个管理数据集合的类,正常情况下,如果查询得到的数据量较小时不会有内存问题,而且虚拟机能够保证Cusor最终会被释放掉。 然而如果Cursor的数据量特表大,特别是如果里面有Blob信息时,应该保证Cursor占用的内存被及时的释放掉,而不是等待GC来处理。并且Android明显是倾向于编程者手动的将Cursor close掉,因为在源代码中我们发现,如果等到垃圾回收器来回收时,会给用户以错误提示。 所以我们使用Cursor的方式一般如下:Cursor cursor = null; try { cursor = mContext.getContentResolver().query(uri,null, null,null,null); if(cursor != null) { cursor.moveToFirst(); //do something } } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) { cursor.close(); } } 有一种情况下,我们不能直接将Cursor关闭掉,这就是在CursorAdapter中应用的情况,但是注意,CursorAdapter在Acivity结束时并没有自动的将Cursor关闭掉,因此,你需要在onDestroy函数中,手动关闭。@Overrideprotected void onDestroy() { if (mAdapter != null && mAdapter.getCurosr() != null) { mAdapter.getCursor().close(); } super.onDestroy(); } CursorAdapter中的changeCursor函数,会将原来的Cursor释放掉,并替换为新的Cursor,所以你不用担心原来的Cursor没有被关闭。 你可能会想到使用Activity的managedQuery来生成Cursor,这样Cursor就会与Acitivity的生命周期一致了,多么完美的解决方法!然而事实上managedQuery也有很大的局限性。 managedQuery生成的Cursor必须确保不会被替换,因为可能很多程序事实上查询条件都是不确定的,因此我们经常会用新查询的Cursor来替换掉原先的Cursor。因此这种方法适用范围也是很小。 七、其它要说的。 其实,要减小内存的使用,其实还有很多方法和要求。比如不要使用整张整张的图,尽量使用9path图片。Adapter要使用convertView等等,好多细节都可以节省内存。这些都需要我们去挖掘,谁叫Android的内存不给力来着。... 全文

android Android ANDROID

Android开发入门:Android SDK介绍

1.Android SDK即Android Software Development Kit.它提供了在Windows/Linux/Mac平台上开发Android应用的开发组件,包含了在Android平台上开发移动应用程序的各种工具集。2.Android SDK tools1).Android模拟器(Android Emulator(emulator.exe))运行在计算机上的虚拟移动模拟器,可以使用模拟器来在一个实际的Android运行环境下 设计,调试和测试应用程序。... 全文

Android开发 Android SDK

Android ApiDemo 惯用代码解析

一、关于Dialog|--- com.example.android.apis.app/AlertDialogSamples.java里面包含了Dialog的各种用法,有10种不同的Dialog实例。|--- com.example.android.apis.app/FragmentDialog.java... 全文

Android ApiDemo Android开发 Android SDK

Android ApiDemo示例解读8:Activity

我们在前面介绍过Hello world示例,这里的Hello world 的Layout定义稍有不同:... 全文

Android ApiDemo Android开发 Android SDK

Android ApiDemo示例解读3:App

SDK中的示例程序App->Activity->Animation演示了切换Activity时的动画效果。提供了两种动画效果,一种是Fade In渐变,后出现的Activity由浅入深逐渐显示;另一种是Zoom放大效果,后出现的Activity由小及大逐渐显示。Android 中 Animation 资源可以分为两种:Tween Animation 对单个图像进行各种变换(缩放,平移,旋转等)来实现动画。... 全文

Android ApiDemo Android开发 Android SDK

关于Android的selector小用法

android的selector(背景选择器)关于listview,imageview和imagebutton,button等空间都要改变android原来控件的背景,网上资料不是很全,所以现在总结一下android的selector的用法。 首先android的selector是在drawable/xxx.xml中配置的。 先看一下listview中的状态: 把下面的XML文件保存成你自己命名的.xml文件(比如list_item_bg.xml),在系统使用时根据ListView中的列表项的状态来使用相应的背景图片。 drawable/list_item_bg.xml <?xml version="1.0" encoding="utf-8" ?>   <selector xmlns:androfont-family: Arial">http://schemas.android.com/apk/res/android"> <!-- 默认时的背景图片 -->    <item android:drawable="@drawable/pic1" />   <!-- 没有焦点时的背景图片 -->    <item android:state_window_focused="false"            android:drawable="@drawable/pic1" />   <!-- 非触摸模式下获得焦点并单击时的背景图片 -->    <item android:state_focused="true" android:state_pressed="true"           android:drawable= "@drawable/pic2" />  <!-- 触摸模式下单击时的背景图片 -->    <item android:state_focused="false" android:state_pressed="true"           android:drawable="@drawable/pic3" />   <!--选中时的图片背景  -->    <item android:state_selected="true"           android:drawable="@drawable/pic4" />   <!--获得焦点时的图片背景  -->    <item android:state_focused="true"           android:drawable="@drawable/pic5" />   </selector> 使用些xml文件:第一种是在listview中配置android:listSelector="@drawable/list_item_bg 或者在listview的item中添加属性android:background=“@drawable/list_item_bg"即可实现,或者在java代码中使用:Drawable drawable = getResources().getDrawable(R.drawable.list_item_bg);         ListView.setSelector(drawable);同样的效果。 但是这样会出现列表有时候为黑的情况,需要加上:android:cacheColorHint="@android:color/transparent" 使其透明。 其次再来看看Button的一些背景效果: android:state_selected是选中 android:state_focused是获得焦点 android:state_pressed是点击 android:state_enabled是设置是否响应事件,指所有事件 根据这些状态同样可以设置button的selector效果。也可以设置selector改变button中的文字状态。 以下就是配置button中的文字效果: drawable/button_font.xml <?xml version="1.0" encoding="utf-8"?> <selector xmlns:androfont-family: Arial">http://schemas.android.com/apk/res/android">     <item android:state_selected="true" android:color="#FFF" />     <item android:state_focused="true" android:color="#FFF" />     <item android:state_pressed="true" android:color="#FFF" />     <item android:color="#000" /> </selector> Button还可以实现更复杂的效果,例如渐变啊等等。 drawable/button_color.xml <?xml version="1.0" encoding="utf-8"?> <selector xmlns:androfont-family: Arial">http://schemas.android.com/apk/res/android">         /         <item android:state_pressed="true">//定义当button 处于pressed 状态时的形态。               <shape>                      <gradient  android:startColor="#8600ff" />                       <stroke   android:width="2dp" android:color="#000000" />                        <corners android:radius="5dp" />                         <padding android:left="10dp" android:top="10dp"                                 android:bottom="10dp" android:right="10dp"/>                   </shape>         </item>         <item android:state_focused="true">//定义当button获得 focus时的形态                  <shape>                        <gradient android:startColor="#eac100"/>                         <stroke android:width="2dp" android:color="#333333"  color="#ffffff"/>                          <corners android:radius="8dp" />                            <padding android:left="10dp" android:top="10dp"                                   android:bottom="10dp" android:right="10dp"/>                                  </shape>             </item> </selector>      最后,需要在包含 button的xml文件里添加两项。假如是 main.xml 文件, 我们需要在<Button />里加两项。      android:focusable="true"      android:backgroud="@drawable/button_color" 这样当你使用Button的时候就可以甩掉系统自带的那黄颜色的背景了,实现个性化的背景,配合应用的整体布局非常之有用啊。... 全文

android selector android按压 android动态

Android ApiDemo示例解读7:Activity

Android应用可以包含,多个Activity, 某个Activity可以启动另外的Activity。这些Activity采用栈结构来管理,新打开的Activity叠放在当前的Activity之 上,当前的Activity停止运行。当一个Activity停止运行时,Android系统保留其停止前的状态,当用户按下“Back”按键时,栈最上 的Activity从栈顶退栈,之前的Activity移到栈顶,显示在屏幕上:... 全文

Android ApiDemo Android开发 Android SDK

盘点Android应用程序商店类型

Android Market 装着什么,他们的梦想么?怀揣成为Android乱世中另一个“App Store”的梦想,无论是硬件厂商、ROM 制作者、浏览器还是 B2C 行业的寡头,纷纷推出各自的应用商店,名字叫法不尽相同,但目的只有一个:在蓬勃发展的移动互联网市场中,利用自身积累的优势资源,借助已经取得成功的App Store模式,完成抢滩登陆的战役。而App Store模式的商业竞争中,总会提到两个要点:用户与内容。... 全文

Android应用程序商店 Android Market Android

使用Gradle构建Android项目

在前一阵子的Google IO大会上我注意到Android Studio开发环境引起了大家的关注。我发现Eclipse经常会变慢而且健壮性不强,所以一个新的替代Android IDE是最受欢迎的消息。在仔细关注这次的发布时,我发现另一个亮点是基于Gradle的Android项目新的构建系统。因此我决定更仔细地了解Gradle。下面列举了一些使用Gradle构建Android项目的好处:- 在IDE环境和命令行下使用同一个构建系统- 改进的依赖关系管理- 更容易地集成到自动化构建系统... 全文

Gradle构建Android项目 Android开发 Android学习

Android ApiDemo示例解读5:Activity

Android UI缺省的标题栏由android:label 定义,显示在屏幕左上角,Android允许Activity自定义标题栏,使用自定义Layout重新设置标题栏,比如实现Windows Mobile 风格的标题栏。App->Activity->Custom Title 重新将Activity标题栏定义为左右两个文本框,其Layout定义R.layout.custom_title_1如下:(下面的xml中包含了一左一右两个文本框。... 全文

Android ApiDemo Android开发 Android SDK

Android ApiDemo示例解读2:ListActivity

如上一节中所讲的那样创建了ApiDemo工程后,我们就可以进行每个示例代码的分析了。读者应对Android开发有基本的了解或读过Android开发方面的基础教程。... 全文

Android ApiDemo Android开发 Android SDK

Android ApiDemo示例解读9:Activity

Android 提供了多种存储数据的方法,其中最简单的是使用Shared Preferences。Shared Preferences 可以存储 Key/value 对,Shared Preferences 支持存取 boolean, float ,long ,integer, string ,最常用的使用Shared Preferences是用来存储一些应用偏好。此外的一个方法是使用onSaveInstanceState(),这是特别用来保存UI 状态的。... 全文

Android ApiDemo Android开发 Android SDK

Android ApiDemo示例解读6:App

上一节中讲了App->Activity->Custom Title的示例,本节来讲讲App->Activity->Dialog。... 全文

Android ApiDemo Android开发 Android SDK

如何定位Android NDK开发中遇到的错误

Android NDK是什么? Android NDK 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google称为“NDK”。众所周知,Android程序运行在Dalvik虚拟机中,NDK允许用户使用类似C / C++之类的原生代码语言执行部分程序。NDK包括:从C / C++生成原生代码库所需要的工具和build files;将一致的原生库嵌入可以在Android设备上部署的应用程序包文件(application packages files ,即.apk文件)中;支持所有未来Android平台的一系列原生系统头文件和库。 为何要用到NDK?概括来说主要分为以下几种情况:... 全文

Android android ndk android开发

Android UI之Android Layout XML属性

Layout对于迅速的搭建界面和提高界面在不同分辨率的屏幕上的适应性具有很大的作用。这里简要介绍Android的Layout和研究一下它的实现。Android有Layout:FrameLayout,LinearLayout,TableLayout,RelativeLayout,AbsoluteLayout。放入Layout中进行排布的View的XML属性:1.几种Layout中Item所共有的XML属性:(1)layout_width(2)layout_height... 全文

Android开发 Android UI Layout XML属性

Android ApiDemo示例解读4::Activity

在Android Demo实例App->Activity->Custom Dialog中,使用Activity来实现自定义对话框,类CustomDialogActivity本身无任何特别之处。关键的一点是其在AndroidManifest.xml中的定义:... 全文

Android ApiDemo Android开发 Android SDK

Android NDK环境搭建及sample展示

1  下载NDK        略过。。。2   配置环境        2.1 在~目录下执行命令:open .bash_profile        2.2 在打开文件中添加                      ANDROID_NDK_ROOT=/Users/lincoln/Android/ndk                export ANDROID_NDK_ROOT        2.3 执行 source .bash_profile        2.4 执行ndk-build,出现下图,说明配置环境成功... 全文

android ndk 环境搭建 Android NDK android ndk

Android那些事儿 Android手机交互特性(1)

Android那些事儿 Android手机交互特性

接上文《Android那些事儿 成长中的Android 》。本文描述了与其它触屏手机系统和桌面系统不同的Android平台特性,这些特性需要更多的表现在我们开发的应用程序中,以保证这是一款Android手机的应用。这些特性可能对于习惯了其它手机操作系统的用户可能有不习惯的地方,需要重新学习和... 全文

Android Android手机 交互设计

Akita 一套Android快速开发库 发布1.2版本

项目主页: http://xjanker.github.com/akita/目前是1.2版本,欢迎使用。并积极加入开源代码贡献中来。... 全文

akita android Android ANDROID

3 4 5 6 7 8 9 10 11 12