<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>爱周末 &#187; Android</title>
	<atom:link href="http://zhoumo123.cn/tag/android/feed" rel="self" type="application/rss+xml" />
	<link>http://zhoumo123.cn</link>
	<description>知识分享，共同进步。zhoumo123.cn</description>
	<lastBuildDate>Thu, 07 Nov 2019 05:53:49 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.0.1</generator>
	<item>
		<title>Android-高效加载图片经验分享</title>
		<link>http://zhoumo123.cn/android/3260.html</link>
		<comments>http://zhoumo123.cn/android/3260.html#comments</comments>
		<pubDate>Tue, 01 Sep 2015 07:44:43 +0000</pubDate>
		<dc:creator><![CDATA[zhangc]]></dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://zhoumo123.cn/?p=3260</guid>
		<description><![CDATA[在编写Android程序的时候经常要用到许多图片，不同图片总是会有不同的形状、不同的大小，但在大多数情况下，这些图片都会大于我们程序所需要的大小。比如说系统图片库里展示的图片大都是用手机摄像头拍出来的，这些图片的分辨率会比我们手机屏幕的分辨率高得多。大家应该知道，我们编写的应用程序都是有一定内存限制的，程序占用了过高的内存就容易出现OOM(OutOfMemory)异常。图片的优化，可以给用户良好的体验，美化程序界面以及避免程序出现OOM。下面这篇文章告诉我们可以通过代码看出每个应用程序最高可用内存是多少，当然我们可以通过第三方工具来对APP性能进行检测：http://www.ineice.co ...  <a href="http://zhoumo123.cn/android/3260.html">  阅读全文 </a>]]></description>
				<content:encoded><![CDATA[<p>在编写Android程序的时候经常要用到许多图片，不同图片总是会有不同的形状、不同的大小，但在大多数情况下，这些图片都会大于我们程序所需要的大小。比如说系统图片库里展示的图片大都是用手机摄像头拍出来的，这些图片的分辨率会比我们手机屏幕的分辨率高得多。大家应该知道，我们编写的应用程序都是有一定内存限制的，程序占用了过高的内存就容易出现OOM(OutOfMemory)异常。图片的优化，可以给用户良好的体验，美化程序界面以及避免程序出现OOM。下面这篇文章告诉我们可以通过代码看出每个应用程序最高可用内存是多少，当然我们可以通过第三方工具来对APP性能进行检测：http://www.ineice.com/</p>
<p>int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024);<br />
Log.d(&#8220;TAG&#8221;, &#8220;Max memory is&#8221; + maxMemory + &#8220;KB&#8221;);</p>
<p>因此在展示高分辨率图片的时候，最好先将图片进行压缩。压缩后的图片大小应该和用来展示它的控件大小相近，在一个很小的ImageView上显示一张超大的图片不会带来任何视觉上的好处，但却会占用我们相当多宝贵的内存，而且在性能上还可能会带来负面影响。下面我们就来看一看，如何对一张大图片进行适当的压缩，让它能够以最佳大小显示的同时，还能防止OOM的出现。<br />
BitmapFactory这个类提供了多个解析方法(decodeByteArray,decodeFile, decodeResource等)用于创建Bitmap对象，我们应该根据图片的来源选择合适的方法。比如SD卡中的图片可以使用decodeFile方法，网络上的图片可以使用decodeStream方法，资源文件中的图片可以使用decodeResource方法。这些方法会尝试为已经构建的bitmap分配内存，这时就会很容易导致OOM出现。为此每一种解析方法都提供了一个可选的BitmapFactory.Options参数，将这个参数的inJustDecodeBounds属性设置为true就可以让解析方法禁止为bitmap分配内存，返回值也不再是一个Bitmap对象，而是null。虽然Bitmap是null了，但是BitmapFactory.Options的outWidth、outHeight和outMimeType属性都会被赋值。这个技巧让我们可以在加载图片之前就获取到图片的长宽值和MIME类型，从而根据情况对图片进行压缩。如下代码所示：</p>
<p> view plaincopy<br />
BitmapFactory.Options options = newBitmapFactory.Options();<br />
options.inJustDecodeBounds = true;<br />
BitmapFactory.decodeResource(getResources(),R.id.myimage, options);<br />
int imageHeight = options.outHeight;<br />
int imageWidth = options.outWidth;<br />
String imageType =options.outMimeType;<br />
为了避免OOM异常，最好在解析每张图片的时候都先检查一下图片的大小，除非你非常信任图片的来源，保证这些图片都不会超出你程序的可用内存。<br />
现在图片的大小已经知道了，我们就可以决定是把整张图片加载到内存中还是加载一个压缩版的图片到内存中。以下几个因素是我们需要考虑的：</p>
<p>预估一下加载整张图片所需占用的内存。<br />
为了加载这一张图片你所愿意提供多少内存。<br />
用于展示这张图片的控件的实际大小。<br />
当前设备的屏幕尺寸和分辨率。<br />
比如，你的ImageView只有128*96像素的大小，只是为了显示一张缩略图，这时候把一张1024*768像素的图片完全加载到内存中显然是不值得的。</p>
<p>那我们怎样才能对图片进行压缩呢？通过设置BitmapFactory.Options中inSampleSize的值就可以实现。比如我们有一张2048*1536像素的图片，将inSampleSize的值设置为4，就可以把这张图片压缩成512*384像素。原本加载这张图片需要占用13M的内存，压缩后就只需要占用0.75M了(假设图片是ARGB_8888类型，即每个像素点占用4个字节)。下面的方法可以根据传入的宽和高，计算出合适的inSampleSize值：</p>
<p> view plaincopy<br />
public static intcalculateInSampleSize(BitmapFactory.Options options,<br />
int reqWidth, int reqHeight) {<br />
// 源图片的高度和宽度<br />
final int height = options.outHeight;<br />
final int width = options.outWidth;<br />
int inSampleSize = 1;<br />
if (height &gt; reqHeight || width &gt; reqWidth) {<br />
// 计算出实际宽高和目标宽高的比率<br />
final int heightRatio = Math.round((float) height / (float)reqHeight);<br />
final int widthRatio = Math.round((float) width / (float)reqWidth);<br />
// 选择宽和高中最小的比率作为inSampleSize的值，这样可以保证最终图片的宽和高<br />
// 一定都会大于等于目标的宽和高。<br />
inSampleSize = heightRatio &lt; widthRatio ? heightRatio : widthRatio;<br />
}<br />
return inSampleSize;<br />
}<br />
使用这个方法，首先你要将BitmapFactory.Options的inJustDecodeBounds属性设置为true，解析一次图片。然后将BitmapFactory.Options连同期望的宽度和高度一起传递到到calculateInSampleSize方法中，就可以得到合适的inSampleSize值了。之后再解析一次图片，使用新获取到的inSampleSize值，并把inJustDecodeBounds设置为false，就可以得到压缩后的图片了。<br />
 view plaincopy<br />
public static BitmapdecodeSampledBitmapFromResource(Resources res, int resId,<br />
int reqWidth, int reqHeight) {<br />
// 第一次解析将inJustDecodeBounds设置为true，来获取图片大小<br />
final BitmapFactory.Options options = new BitmapFactory.Options();<br />
options.inJustDecodeBounds = true;<br />
BitmapFactory.decodeResource(res, resId, options);<br />
// 调用上面定义的方法计算inSampleSize值<br />
options.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);<br />
// 使用获取到的inSampleSize值再次解析图片<br />
options.inJustDecodeBounds = false;<br />
return BitmapFactory.decodeResource(res, resId, options);<br />
}<br />
下面的代码非常简单地将任意一张图片压缩成100*100的缩略图，并在ImageView上展示。<br />
 view plaincopy<br />
mImageView.setImageBitmap(<br />
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100,100));<br />
使用图片缓存技术<br />
在你应用程序的UI界面加载一张图片是一件很简单的事情，但是当你需要在界面上加载一大堆图片的时候，情况就变得复杂起来。在很多情况下，（比如使用ListView, GridView 或者 ViewPager 这样的组件），屏幕上显示的图片可以通过滑动屏幕等事件不断地增加，最终导致OOM。<br />
为了保证内存的使用始终维持在一个合理的范围，通常会把被移除屏幕的图片进行回收处理。此时垃圾回收器也会认为你不再持有这些图片的引用，从而对这些图片进行GC操作。用这种思路来解决问题是非常好的，可是为了能让程序快速运行，在界面上迅速地加载图片，你又必须要考虑到某些图片被回收之后，用户又将它重新滑入屏幕这种情况。这时重新去加载一遍刚刚加载过的图片无疑是性能的瓶颈，你需要想办法去避免这个情况的发生。</p>
<p>这个时候，使用内存缓存技术可以很好的解决这个问题，它可以让组件快速地重新加载和处理图片。下面我们就来看一看如何使用内存缓存技术来对图片进行缓存，从而让你的应用程序在加载很多图片的时候可以提高响应速度和流畅性。</p>
<p>内存缓存技术对那些大量占用应用程序宝贵内存的图片提供了快速访问的方法。其中最核心的类是LruCache (此类在android-support-v4的包中提供) 。这个类非常适合用来缓存图片，它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中，并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。<br />
在过去，我们经常会使用一种非常流行的内存缓存技术的实现，即软引用或弱引用 (SoftReference or WeakReference)。但是现在已经不再推荐使用这种方式了，因为从 Android 2.3 (API Level 9)开始，垃圾回收器会更倾向于回收持有软引用或弱引用的对象，这让软引用和弱引用变得不再可靠。另外，Android 3.0 (API Level 11)中，图片的数据会存储在本地的内存当中，因而无法用一种可预见的方式将其释放，这就有潜在的风险造成应用程序的内存溢出并崩溃。<br />
为了能够选择一个合适的缓存大小给LruCache, 有以下多个因素应该放入考虑范围内，例如：</p>
<p>你的设备可以为每个应用程序分配多大的内存？<br />
设备屏幕上一次最多能显示多少张图片？有多少图片需要进行预加载，因为有可能很快也会显示在屏幕上？<br />
你的设备的屏幕大小和分辨率分别是多少？一个超高分辨率的设备（例如 Galaxy Nexus) 比起一个较低分辨率的设备（例如 Nexus S），在持有相同数量图片的时候，需要更大的缓存空间。<br />
图片的尺寸和大小，还有每张图片会占据多少内存空间。<br />
图片被访问的频率有多高？会不会有一些图片的访问频率比其它图片要高？如果有的话，你也许应该让一些图片常驻在内存当中，或者使用多个LruCache 对象来区分不同组的图片。<br />
你能维持好数量和质量之间的平衡吗？有些时候，存储多个低像素的图片，而在后台去开线程加载高像素的图片会更加的有效。<br />
并没有一个指定的缓存大小可以满足所有的应用程序，这是由你决定的。你应该去分析程序内存的使用情况，然后制定出一个合适的解决方案。一个太小的缓存空间，有可能造成图片频繁地被释放和重新加载，这并没有好处。而一个太大的缓存空间，则有可能还是会引起 java.lang.OutOfMemory 的异常。<br />
下面是一个使用 LruCache 来缓存图片的例子：</p>
<p> view plaincopy<br />
private LruCache&lt;String, Bitmap&gt;mMemoryCache;</p>
<p>@Override<br />
protected void onCreate(BundlesavedInstanceState) {<br />
// 获取到可用内存的最大值，使用内存超出这个值会引起OutOfMemory异常。<br />
// LruCache通过构造函数传入缓存值，以KB为单位。<br />
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);<br />
// 使用最大可用内存值的1/8作为缓存的大小。<br />
int cacheSize = maxMemory / 8;<br />
mMemoryCache = new LruCache&lt;String, Bitmap&gt;(cacheSize) {<br />
@Override<br />
protected int sizeOf(String key, Bitmap bitmap) {<br />
// 重写此方法来衡量每张图片的大小，默认返回图片数量。<br />
return bitmap.getByteCount() / 1024;<br />
}<br />
};<br />
}</p>
<p>public void addBitmapToMemoryCache(Stringkey, Bitmap bitmap) {<br />
if (getBitmapFromMemCache(key) == null) {<br />
mMemoryCache.put(key, bitmap);<br />
}<br />
}</p>
<p>public Bitmap getBitmapFromMemCache(Stringkey) {<br />
return mMemoryCache.get(key);<br />
}</p>
<p>在这个例子当中，使用了系统分配给应用程序的八分之一内存来作为缓存大小。在中高配置的手机当中，这大概会有4兆(32/8)的缓存空间。一个全屏幕的 GridView 使用4张 800&#215;480分辨率的图片来填充，则大概会占用1.5兆的空间(800*480*4)。因此，这个缓存大小可以存储2.5页的图片。<br />
当向 ImageView 中加载一张图片时,首先会在 LruCache 的缓存中进行检查。如果找到了相应的键值，则会立刻更新ImageView ，否则开启一个后台线程来加载这张图片。<br />
 view plaincopy<br />
public void loadBitmap(int resId, ImageViewimageView) {<br />
final String imageKey = String.valueOf(resId);<br />
final Bitmap bitmap = getBitmapFromMemCache(imageKey);<br />
if (bitmap != null) {<br />
imageView.setImageBitmap(bitmap);<br />
}else {<br />
imageView.setImageResource(R.drawable.image_placeholder);<br />
BitmapWorkerTask task = new BitmapWorkerTask(imageView);<br />
task.execute(resId);<br />
}<br />
}<br />
BitmapWorkerTask 还要把新加载的图片的键值对放到缓存中。<br />
 view plaincopy<br />
class BitmapWorkerTask extendsAsyncTask&lt;Integer, Void, Bitmap&gt; {<br />
// 在后台加载图片。<br />
@Override<br />
protected Bitmap doInBackground(Integer&#8230; params) {<br />
final Bitmap bitmap = decodeSampledBitmapFromResource(<br />
getResources(), params[0], 100,100);<br />
addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);<br />
return bitmap;<br />
｝</p>
<p>&nbsp;</p>
<p>http://ineice.blog.51cto.com/10426190/1690402</p>
]]></content:encoded>
			<wfw:commentRss>http://zhoumo123.cn/android/3260.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>android 获取application下meta-data中的值</title>
		<link>http://zhoumo123.cn/android/3258.html</link>
		<comments>http://zhoumo123.cn/android/3258.html#comments</comments>
		<pubDate>Tue, 01 Sep 2015 07:23:53 +0000</pubDate>
		<dc:creator><![CDATA[zhangc]]></dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://zhoumo123.cn/?p=3258</guid>
		<description><![CDATA[meta-data在AndroidManifest中是以键值对的形式存在的，可以将meta-data放在application根节点下，也可以放在某个activity节点下。因为存放的位置不同，因此获取value时也要使用对应的方法，下面是我写的一个小测试。 代码如下： 先是在AndroidManifest中的application和mainActivity下添加两个meta-data属性。 接下来在mainActivity中来获取这两个属性的值。 源码下载：http://download.csdn.net/detail/u012527802/9070361 来源：http://blog.cs ...  <a href="http://zhoumo123.cn/android/3258.html">  阅读全文 </a>]]></description>
				<content:encoded><![CDATA[<p>meta-data在AndroidManifest中是以键值对的形式存在的，可以将meta-data放在application根节点下，也可以放在某个activity节点下。因为存放的位置不同，因此获取value时也要使用对应的方法，下面是我写的一个小测试。</p>
<p>代码如下：</p>
<p>先是在AndroidManifest中的application和mainActivity下添加两个meta-data属性。</p>
<pre class="brush: java; title: ; notranslate">
    &lt;application
        android:allowBackup=&quot;true&quot;
        android:icon=&quot;@drawable/ic_launcher&quot;
        android:label=&quot;@string/app_name&quot;
        android:theme=&quot;@style/AppTheme&quot; &gt;
        &lt;meta-data
            android:name=&quot;com.lzy.test&quot;
            android:value=&quot;测试&quot; /&gt;

        &lt;activity
            android:name=&quot;.MainActivity&quot;
            android:label=&quot;@string/app_name&quot; &gt;
            &lt;meta-data
                android:name=&quot;com.example.metatest.MainActivity.com.lzy.activity.test&quot;
                android:value=&quot;Activity测试&quot; /&gt;

            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;

                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
    &lt;/application&gt;
    
 </pre>
<p>接下来在mainActivity中来获取这两个属性的值。</p>
<pre class="brush: java; title: ; notranslate">
package com.example.metatest;

import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

/**
 * meta 测试
 * 
 * @author Administrator
 * 
 */

public class MainActivity extends Activity {

	public static final String TEST = &quot;com.lzy.test&quot;;

	public static final String ACTIVITYTEST = MainActivity.class.getName()+&quot;.com.lzy.activity.test&quot;;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		String test = getMetaDataStringApplication(TEST, null);
		
		String activityTest = getMetaDataStringFromActivity(ACTIVITYTEST, null);
		
		Toast.makeText(this, test+&quot;--&quot;+activityTest, Toast.LENGTH_LONG).show();
	}
	
	/**
	 * 根据key从Application中返回的Bundle中获取value
	 * 
	 * @param key
	 * @param defValue
	 * @return
	 */
	private String getMetaDataStringApplication(String key, String defValue) {
		Bundle bundle = getAppMetaDataBundle(getPackageManager(), getPackageName());
		if (bundle != null &amp;&amp; bundle.containsKey(key)) {
			return bundle.getString(key);
		}
		return defValue;
	}
	
	/**
	 * 获取Application中的meta-data.
	 * 
	 * @param packageManager
	 * @param packageName
	 * @return
	 */
	private Bundle getAppMetaDataBundle(PackageManager packageManager,
			String packageName) {
		Bundle bundle = null;
		try {
			ApplicationInfo ai = packageManager.getApplicationInfo(packageName,
					PackageManager.GET_META_DATA);
			bundle = ai.metaData;
		} catch (NameNotFoundException e) {
			Log.e(&quot;getMetaDataBundle&quot;, e.getMessage(), e);
		}
		return bundle;
	}
	
	/**
	 * 根据key从Activity中返回的Bundle中获取value
	 * 
	 * @param key
	 * @param defValue
	 * @return
	 */
	private String getMetaDataStringFromActivity(String key, String defValue) {
		Bundle bundle = getActivityMetaDataBundle(getPackageManager(), getComponentName());
		if (bundle != null &amp;&amp; bundle.containsKey(key)) {
			return bundle.getString(key);
		}
		return defValue;
	}
	
	/**
	 * 获取Activity中的meta-data.
	 * 
	 * @param packageManager
	 * @param component
	 * @return
	 */
	private Bundle getActivityMetaDataBundle(PackageManager packageManager, ComponentName component) {
		Bundle bundle = null;
		try {
			ActivityInfo ai = packageManager.getActivityInfo(component,
					PackageManager.GET_META_DATA);
			bundle = ai.metaData;
		} catch (NameNotFoundException e) {
			Log.e(&quot;getMetaDataBundle&quot;, e.getMessage(), e);
		}

		return bundle;
	}

}
    
</pre>
<p>源码下载：http://download.csdn.net/detail/u012527802/9070361</p>
<p>来源：http://blog.csdn.net/u012527802/article/details/48157637</p>
]]></content:encoded>
			<wfw:commentRss>http://zhoumo123.cn/android/3258.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android系统的启动时间统计Android内核开发</title>
		<link>http://zhoumo123.cn/android/2922.html</link>
		<comments>http://zhoumo123.cn/android/2922.html#comments</comments>
		<pubDate>Thu, 18 Jun 2015 04:03:21 +0000</pubDate>
		<dc:creator><![CDATA[zhangc]]></dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://zhoumo123.cn/?p=2922</guid>
		<description><![CDATA[如何统计Android系统的启动时间呢？下面这篇文章来简单介绍一下如何统计Android系统的启动时间。 这里所说的统计系统的启动时间，并不是简单地用秒表和肉眼来统计，而是通过分析系统输出的log信息来统计，这样才显得更加专业。 首先了解2个概念： （1） Android是基于Linux内核的系统，因此Android的启动过程是分为两个阶段的，第一个阶段就是Linux内核的启动，第二个阶段就是Android框架的启动（包括核心服务和程序）。 （2）Android的log系统是独立于Linux内核的log系统的。Linux内核通过printk打印的log信息，这些log写入到了/dev/kmsg ...  <a href="http://zhoumo123.cn/android/2922.html">  阅读全文 </a>]]></description>
				<content:encoded><![CDATA[<p>如何统计Android系统的启动时间呢？下面这篇文章来简单介绍一下如何统计Android系统的启动时间。</p>
<p>这里所说的统计系统的启动时间，并不是简单地用秒表和肉眼来统计，而是通过分析系统输出的log信息来统计，这样才显得更加专业。</p>
<p><strong>首先了解2个概念：</strong></p>
<p>（1） Android是基于Linux内核的系统，因此Android的启动过程是分为两个阶段的，第一个阶段就是Linux内核的启动，第二个阶段就是Android框架的启动（包括核心服务和程序）。</p>
<p>（2）Android的log系统是独立于Linux内核的log系统的。Linux内核通过printk打印的log信息，这些log写入到了/dev/kmsg文件中，在Shell终端可以通过dmesg命令查看这些log信息。Android框架则是通过Logger驱动打印log信息，这些log并没有归并到kmesg文件中，而是单独存储的，位于/dev/log目录下，在Shell终端可以通过logcat命令来查看。</p>
<p>下面我们分别从两种log信息中找到如何统计系统启动时间的方法。</p>
<p><strong>1. 通过dmesg信息统计系统启动时间</strong></p>
<p>首先，我们通过dmesg命令抓取Linux内核的log信息（部分系统可能需要先执行 adb root）：</p>
<p><span style="color: #008000;">$ adb shell dmesg &gt; dmesg.txt</span></p>
<p>Linux内核启动完成，一般都有如下的标准输出信息：</p>
<p><span style="color: #008000;">&lt;6&gt; [ 6.613861] Freeing init memory: 176K</span></p>
<p>因此，只要我们在dmesg.txt文件中找到<span style="color: #008000;">“Freeing init memory”</span>这一行即可，从上面的log可以看出，Linux内核启动只用了6.613861s。</p>
<p><strong>那么，如何找到Android系统启动完成的标志呢？</strong></p>
<p>很多Android设备在系统启动完成后，会在内核log中打印如下信息：</p>
<p><span style="color: #008000;">&lt;6&gt;[ 29.913726] init: processing action 0x96bb8 (property:sys.boot_completed=1)</span></p>
<p>因此，找到<span style="color: #008000;">“boot_completed”</span>这一行也就得到了整个系统的启动时间了，从这一行可以看出，整个系统启动用了29.913726s。</p>
<p>当然，并不是所有的Android设备都会打印出这条log，因此，我们一般用下面介绍的方法来专门统计Android系统的启动时间，</p>
<p><strong>2. 通过logcat统计系统的启动时间</strong></p>
<p>文章开头我们已经介绍过，Android的log系统是独立于Linux内核log系统的，通过在终端输入adb shell 进入Android系统，cd到/dev/log目录，你会发现里面有四个文件，分别是：<span style="color: #008000;"><strong>events，main，radio，system.</strong></span></p>
<p>Android系统把Log分为了四类，不同的类别记录不同的Log信息：</p>
<p><strong>main &#8211; 主要的Log信息，大部分应用级别的Log信息都在这里</strong><br />
<strong>events &#8211; 系统事件相关的Log信息</strong><br />
<strong>radio &#8211; 无线/电话相关的Log信息</strong><br />
<strong>system &#8211; 低级别的系统调试Log信息</strong></p>
<p>默认通过logcat抓取的是main信息，如果想抓取指定类别的log信息的方法，在logcat命令后加-b参数，例如：</p>
<p><span style="color: #008000;">$ adb logcat -d -v time -b &#8220;main&#8221; &gt; main.txt</span><br />
<span style="color: #008000;">$ adb logcat -d -v time -b &#8220;events&#8221; &gt; events.txt</span><br />
<span style="color: #008000;">$ adb logcat -d -v time -b &#8220;system&#8221; &gt; system.txt</span><br />
<span style="color: #008000;">$ adb logcat -d -v time -b &#8220;radio&#8221; &gt; radio.txt</span></p>
<p>&nbsp;</p>
<p>关于Android Log系统的分类，你可以访问如下页面详细了解： 《Android Logging System》</p>
<p><strong>那么，如何统计Android系统的启动时间呢？</strong></p>
<p>我们可以重点关注events类别的log信息，通过如下命令：</p>
<p><span style="color: #008000;">$ adb logcat -d -b events | grep &#8220;boot&#8221;</span></p>
<p>如图所示，这是我在高通的APQ8064开发板上抓取的log信息：</p>
<p><a href="http://zhoumo123.cn/wp-content/uploads/2015/06/AndroidLOG.jpg"><img class="alignnone size-full wp-image-2923" src="http://zhoumo123.cn/wp-content/uploads/2015/06/AndroidLOG.jpg" alt="AndroidLOG" width="624" height="213" /></a></p>
<p><span style="color: #008000;">“boot_progress_start”</span>代表着Android部分启动开始，即15.492s开始启动。</p>
<p><span style="color: #008000;">“boot_progress_enable_screen”</span>代表着整个系统启动结束，即用了29.986s。</p>
<p>&nbsp;<br />
原文：http://ticktick.blog.51cto.com/823160/1660996</p>
]]></content:encoded>
			<wfw:commentRss>http://zhoumo123.cn/android/2922.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android界面设计psd下载Android界面设计欣赏</title>
		<link>http://zhoumo123.cn/psd-sucai/936.html</link>
		<comments>http://zhoumo123.cn/psd-sucai/936.html#comments</comments>
		<pubDate>Fri, 03 Oct 2014 19:03:22 +0000</pubDate>
		<dc:creator><![CDATA[zhangc]]></dc:creator>
				<category><![CDATA[psd素材]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[app设计]]></category>
		<category><![CDATA[图标素材PSD下载]]></category>

		<guid isPermaLink="false">http://zhoumo123.cn/?p=936</guid>
		<description><![CDATA[分享给大家一个Android的界面设计，如果你是Android界面设计人员，可以参考哦，无论在界面布局还是颜色搭配，都非常漂亮。此设计素材为PSD格式。附件中包含Android联系人界面、文件管理界面、按钮等的设计。见下图： 界面截图1： 界面截图2： 界面截图3： 附件中Android界面设计psd文件截图： 下载：Android界面设计psd下载 &#160;]]></description>
				<content:encoded><![CDATA[<p>分享给大家一个Android的界面设计，如果你是Android界面设计人员，可以参考哦，无论在界面布局还是颜色搭配，都非常漂亮。此设计素材为PSD格式。附件中包含Android联系人界面、文件管理界面、按钮等的设计。见下图：</p>
<p>界面截图1：</p>
<p><a href="http://img.zhoumo123.cn/wp-content/uploads/Android-design-1.jpg"><img class="alignnone wp-image-938 size-full" title="Android界面设计" src="http://img.zhoumo123.cn/wp-content/uploads/Android-design-1.jpg" alt="Android界面设计" width="606" height="349" /></a></p>
<p>界面截图2：</p>
<p><a href="http://img.zhoumo123.cn/wp-content/uploads/Android-design-0.jpg"><img class="alignnone wp-image-937 size-full" title="Android界面设计" src="http://img.zhoumo123.cn/wp-content/uploads/Android-design-0.jpg" alt="Android界面设计" width="369" height="648" /></a></p>
<p>界面截图3：</p>
<p><a href="http://img.zhoumo123.cn/wp-content/uploads/Android-design-2.jpg"><img class="alignnone wp-image-939 size-full" title="Android界面设计" src="http://img.zhoumo123.cn/wp-content/uploads/Android-design-2.jpg" alt="Android界面设计" width="602" height="361" /></a></p>
<p>附件中Android界面设计psd文件截图：</p>
<p><a href="http://img.zhoumo123.cn/wp-content/uploads/Android-design-3.jpg"><img class="alignnone wp-image-940 size-full" title="Android界面设计psd文件" src="http://img.zhoumo123.cn/wp-content/uploads/Android-design-3.jpg" alt="Android界面设计psd文件" width="651" height="162" /></a></p>
<p>下载：<a href="http://img.zhoumo123.cn/wp-content/uploads/up-z/Android_Design.rar">Android界面设计psd下载</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://zhoumo123.cn/psd-sucai/936.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android如何获取屏幕的分辨率</title>
		<link>http://zhoumo123.cn/android/376.html</link>
		<comments>http://zhoumo123.cn/android/376.html#comments</comments>
		<pubDate>Fri, 12 Sep 2014 01:49:55 +0000</pubDate>
		<dc:creator><![CDATA[zhangc]]></dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[android屏幕分辨率]]></category>

		<guid isPermaLink="false">http://zhoumo123.cn/?p=376</guid>
		<description><![CDATA[在实际的项目中，我们经常要得到当前屏幕的分辨率，进行机型适配，得到分辨率其实很简单，主要有两种方法。 方法一： Display mDisplay = getWindowManager().getDefaultDisplay(); int W = mDisplay.getWidth(); int H = mDisplay.getHeight(); Log.i(&#8220;Main&#8221;, &#8220;Width = &#8221; + W); Log.i(&#8220;Main&#8221;, &#8220;Height = &#8221; + H); 复制代码 Display是在a ...  <a href="http://zhoumo123.cn/android/376.html">  阅读全文 </a>]]></description>
				<content:encoded><![CDATA[<p>在实际的项目中，我们经常要得到当前屏幕的分辨率，进行机型适配，得到分辨率其实很简单，主要有两种方法。</p>
<p><strong>方法一：</strong><br />
Display mDisplay = getWindowManager().getDefaultDisplay();<br />
int W = mDisplay.getWidth();<br />
int H = mDisplay.getHeight();<br />
Log.i(&#8220;Main&#8221;, &#8220;Width = &#8221; + W);<br />
Log.i(&#8220;Main&#8221;, &#8220;Height = &#8221; + H);<br />
复制代码<br />
Display是在android.view.Display包中的。</p>
<p><strong>方法二：</strong><br />
DisplayMetrics mDisplayMetrics = new DisplayMetrics();<br />
getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);<br />
int W = mDisplayMetrics.widthPixels;<br />
int H = mDisplayMetrics.heightPixels;<br />
Log.i(&#8220;Main&#8221;, &#8220;Width = &#8221; + W);<br />
Log.i(&#8220;Main&#8221;, &#8220;Height = &#8221; + H);<br />
复制代码<br />
DisplayMetrics是在android.util.DisplayMetrics包中的，getWindowManager()是Activity中的方法。</p>
<p>我使用的测试手机是M9，我们看一下Logcat的打印信息：</p>
<p><a href="http://img.zhoumo123.cn/wp-content/uploads/android-hq1.png"><img class="alignnone size-full wp-image-377" src="http://img.zhoumo123.cn/wp-content/uploads/android-hq1.png" alt="android-hq1" width="956" height="168" /></a></p>
<p>显示正确，M9确实是这个分辨率。</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://zhoumo123.cn/android/376.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android获取手机的型号和系统版本</title>
		<link>http://zhoumo123.cn/android/374.html</link>
		<comments>http://zhoumo123.cn/android/374.html#comments</comments>
		<pubDate>Fri, 12 Sep 2014 01:44:27 +0000</pubDate>
		<dc:creator><![CDATA[zhangc]]></dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[android获取手机信息]]></category>

		<guid isPermaLink="false">http://zhoumo123.cn/?p=374</guid>
		<description><![CDATA[注：android.os.Build.VERSION.RELEASE获取版本号 android.os.Build.MODEL 获取手机型号]]></description>
				<content:encoded><![CDATA[<pre class="brush: java; title: ; notranslate">

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = (TextView) findViewById(R.id.text);
textView.setText(&quot;Product Model: &quot; + android.os.Build.MODEL + &quot;,&quot;
+ android.os.Build.VERSION.SDK + &quot;,&quot;
+ android.os.Build.VERSION.RELEASE);
}

</pre>
<p>注：android.os.Build.VERSION.RELEASE获取版本号<br />
android.os.Build.MODEL 获取手机型号</p>
]]></content:encoded>
			<wfw:commentRss>http://zhoumo123.cn/android/374.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android遇到的异常及解决方法</title>
		<link>http://zhoumo123.cn/android/183.html</link>
		<comments>http://zhoumo123.cn/android/183.html#comments</comments>
		<pubDate>Thu, 24 Jul 2014 12:48:01 +0000</pubDate>
		<dc:creator><![CDATA[zhangc]]></dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://zhoumo123.cn/?p=183</guid>
		<description><![CDATA[1、Warning: Activity not started, its current task has been brought to the front 解：退出模拟器中的应用程序，然后再重启程序！ 2、在添加环境变量的时候发现Tools目录下没有adb.exe文件！所以无法使用命令行 解：发现较新版本的SDK的adb.exe文件在platform-tools文件夹里面 3、在命令行输入adb shell命令时提示错误:error : adb shell device not found 解：开启相应版本的模拟器或者是连接到手机就可以了！ 4、在接收短消息广播的时候出错: require ...  <a href="http://zhoumo123.cn/android/183.html">  阅读全文 </a>]]></description>
				<content:encoded><![CDATA[<p>1、Warning: Activity not started, its current task has been brought to the front</p>
<p>解：退出模拟器中的应用程序，然后再重启程序！</p>
<p>2、在添加环境变量的时候发现Tools目录下没有adb.exe文件！所以无法使用命令行</p>
<p>解：发现较新版本的SDK的adb.exe文件在platform-tools文件夹里面</p>
<p>3、在命令行输入adb shell命令时提示错误:error : adb shell device not found</p>
<p>解：开启相应版本的模拟器或者是连接到手机就可以了！</p>
<p>4、在接收短消息广播的时候出错: requires android.permission.RECEIVE_SMS due to sendercom.android.phone</p>
<p>解：需要在manifest配置一句话：</p>
<p>&lt;uses-permission android:name=&#8221;android.permission.RECEIVE_SMS&#8221;/&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://zhoumo123.cn/android/183.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
