﻿<?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; andriod</title>
	<atom:link href="https://www.softwareace.cn/?cat=97&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>https://www.softwareace.cn</link>
	<description>时刻想着为自己的产品多做一些对他好的事情</description>
	<lastBuildDate>Fri, 20 Mar 2026 06:58:28 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>沉浸式中显示 PopupWindow</title>
		<link>https://www.softwareace.cn/?p=1680</link>
		<comments>https://www.softwareace.cn/?p=1680#comments</comments>
		<pubDate>Tue, 08 Aug 2017 06:53:19 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[andriod]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1680</guid>
		<description><![CDATA[在全屏沉浸模式时（Immersive Full-Screen Mode），如果弹出 Dialog 或 Popu [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="color: #7f8c8d;">在全屏沉浸模式时（Immersive Full-Screen Mode），如果弹出 Dialog 或 PopupWindow，则会自动退出沉浸模式。</p>
<p style="color: #7f8c8d;">退出沉浸式的原因是因为 Activity 的 Window 焦点被抢走了，Window 中的 DecorView 状态改变导致了退出。</p>
<p style="color: #7f8c8d;">如果要继续保持沉浸模式。对于 Dialog 情况，这里有<a style="color: #3498db;" href="http://stackoverflow.com/a/23207365">解决办法</a> 。 Dialog 在初始化时会生成新的 Window，先禁止 Dialog Window 获取焦点，等 Dialog 显示后对 Dialog Window 的 DecorView 设置 <code>setSystemUiVisibility</code> ，接着再获取焦点。 这样表面上看起来就没有退出沉浸模式。</p>
<p style="color: #7f8c8d;">而 PopupWindow 并没有创建新的 Window，只是将 PopupWindow 的 View 添加到当前的 WindowManager。不过可以对 PopupWindow 设置 <code>setFocusable</code>。</p>
<p style="color: #7f8c8d;">同理，先在失焦的状态，弹出 PopupWindow ， 再对 PopupWindow 的 DecorView 设置 <code>setSystemUiVisibility</code> ，最后获取焦点即可。 虽然 PopupWindow 对外没有暴露出 DecorView ，但只要是 PopupWindow 中的可见 View 都行。</p>
<p></p><pre class="crayon-plain-tag">public class MainActivity extends AppCompatActivity {

    private PopupWindow mPopupWindow;

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        int windowWidth = 480;
        int windowHeight = 120;

        TextView popupView = (TextView) LayoutInflater.from(getApplicationContext())
                .inflate(android.R.layout.simple_list_item_1, null);
        popupView.setText("PopupWindow");
        popupView.setGravity(Gravity.CENTER);
        popupView.setBackgroundColor(Color.BLACK);
        popupView.setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "PopupWindow Click", Toast.LENGTH_SHORT)
                        .show();
            }
        });

        mPopupWindow = new PopupWindow(popupView, windowWidth, windowHeight);
        mPopupWindow.setFocusable(false);
        mPopupWindow.setBackgroundDrawable(new ColorDrawable());
        mPopupWindow.setOutsideTouchable(true);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                if (!mPopupWindow.isShowing()) {
                    showPopup(v);
                } else {
                    mPopupWindow.dismiss();
                }
            }
        });
    }

    @Override public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            fullScreenImmersive(getWindow());
        }
    }

    public void showPopup(View anchor) {
        mPopupWindow.setFocusable(false);
        mPopupWindow.update();

        PopupWindowCompat.showAsDropDown(mPopupWindow, anchor,
                -mPopupWindow.getWidth() / 2 + anchor.getWidth() / 2,
                -mPopupWindow.getHeight() - anchor.getHeight(), Gravity.CENTER);

        fullScreenImmersive(mPopupWindow.getContentView());
        mPopupWindow.setFocusable(true);
        mPopupWindow.update();
    }

    public void fullScreenImmersive(Window window) {
        if (window != null) {
            fullScreenImmersive(window.getDecorView());
        }
    }

    public void fullScreenImmersive(View view) {
        if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.KITKAT) {
            int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_FULLSCREEN;
            view.setSystemUiVisibility(uiOptions);
        }
    }
}</pre><p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1680</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一个强悍的android版本检测更新库</title>
		<link>https://www.softwareace.cn/?p=1677</link>
		<comments>https://www.softwareace.cn/?p=1677#comments</comments>
		<pubDate>Thu, 27 Jul 2017 04:14:31 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[andriod]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1677</guid>
		<description><![CDATA[CheckVersionLib 现在热更新技术挺火的，大公司都出了自己的热更新框架，但是各家热更新都有各自优缺 [&#8230;]]]></description>
				<content:encoded><![CDATA[<div>
<h1>CheckVersionLib</h1>
<p>现在热更新技术挺火的，大公司都出了自己的热更新框架，但是各家热更新都有各自优缺点，终究不能解决所有bug，万不得已还是得进行版本升级，这是一个android上的自动版本检测并更新库。库集成了检测版本、下载版本以及自动安装升级</p>
<h2>特点</h2>
<ul>
<li>任何地方都可以检测</li>
<li>任何地方都可以弹出升级对话框</li>
<li>自定义性强，手动回调解析，适用于各种版本检测接口</li>
<li>自动处理下载和升级</li>
<li>自定义界面</li>
<li>支持强制更新</li>
</ul>
<h2>效果</h2>
<div class="image-package"><img src="//upload-images.jianshu.io/upload_images/1982650-a6775406529f9fc1.gif?imageMogr2/auto-orient/strip" alt="" data-original-src="http://upload-images.jianshu.io/upload_images/1982650-a6775406529f9fc1.gif?imageMogr2/auto-orient/strip" /></p>
<div class="image-caption">custom.gif</div>
</div>
<div class="image-package"><img src="//upload-images.jianshu.io/upload_images/1982650-7349fda4332cc577.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300" alt="" data-original-src="http://upload-images.jianshu.io/upload_images/1982650-7349fda4332cc577.png?imageMogr2/auto-orient/strip%7CimageView2/2" /></p>
<div class="image-caption">style1.png</div>
</div>
<div class="image-package"><img src="//upload-images.jianshu.io/upload_images/1982650-906542f3c3aac27b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300" alt="" data-original-src="http://upload-images.jianshu.io/upload_images/1982650-906542f3c3aac27b.png?imageMogr2/auto-orient/strip%7CimageView2/2" /></p>
<div class="image-caption">style2.png</div>
</div>
<h2>使用步骤</h2>
<h3>android studio导入</h3>
<p><code>compile 'com.allenliu.versionchecklib:library:1.0.6'</code></p>
<h3>如何使用</h3>
<p>1.自定义service，service继承 <code>AVersionService</code>，实现其中的 <code>onResponses(AVersionService service, String response)</code>抽象方法.</p>
<p>该方法主要是请求版本接口的回调，由于不同的使用者版本检测接口返回数据类型不一致，所以你需要自定解析数据，然后判断版本号之后调用升级对话框，如果使用库自带的直接调用如下方法: <code>service.showVersionDialog(downloadUrl,title,updateMsg )</code><br />
示例代码:</p><pre class="crayon-plain-tag">&lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (serverVersion &amp;gt; clientVersion) { 
      &lt;span class=&quot;hljs-comment&quot;&gt;//传入下载地址，以及版本更新消息&lt;/span&gt;
     service.showVersionDialog(downloadUrl,&lt;span class=&quot;hljs-built_in&quot;&gt;title&lt;/span&gt;,updateMsg );}</pre><p>如果拿到数据之后，不使用库的方法，那么你可以在回调 里做自己想做的事。记得这里需要自己手动关闭<code>service</code>（如果调用showVersionDialog则不需要手动关闭）</p>
<p>2.在任意地方开启自定义service，并传入<code>VersionParam</code></p><pre class="crayon-plain-tag">versionParams = new VersionParams().setRequestUrl(&lt;span class=&quot;hljs-string&quot;&gt;&quot;http://www.baidu.com&quot;&lt;/span&gt;);
    &lt;span class=&quot;hljs-keyword&quot;&gt;Intent&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;intent&lt;/span&gt; = new &lt;span class=&quot;hljs-keyword&quot;&gt;Intent&lt;/span&gt;(this, DemoService.&lt;span class=&quot;hljs-keyword&quot;&gt;class&lt;/span&gt;);
    &lt;span class=&quot;hljs-keyword&quot;&gt;intent&lt;/span&gt;.putExtra(AVersionService.VERSION_PARAMS_KEY, versionParams);
    startService(&lt;span class=&quot;hljs-keyword&quot;&gt;intent&lt;/span&gt;);</pre><p><code>VersionParams</code>有如下方法，除了requestUrl都是可选值</p>
<div class="image-package"><img src="//upload-images.jianshu.io/upload_images/1982650-e8d0174f4867c86c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="" data-original-src="http://upload-images.jianshu.io/upload_images/1982650-e8d0174f4867c86c.png?imageMogr2/auto-orient/strip%7CimageView2/2" /></p>
<div class="image-caption">versionparams.png</div>
</div>
<h3><strong>自定义界面</strong></h3>
<p>如果想自定义界面，只需创建一个继承自<code>VersionDialogActivity</code>的Activity,Activity设置Theme为透明：</p>
<p><code>android:theme="@style/versionCheckLibvtransparentTheme"</code></p>
<p>开启Service的时候，将自定义的Activity传入VersionParams</p>
<p><code>setCustomDownloadActivityClass(CustomVersionDialogActivity.class)</code></p>
<ul>
<li>自定义 版本dialog,重写 <code>showVersionDialog()</code> ,在里面实现自己的逻辑，最后调用<code>downloadFile(url)</code>或者<code>downloadFile(url,filecallback)</code>注意不要调用父类的方法</li>
<li>自定义 下载中dialog，重写<code>showLoadingDialog(int currentProgress)</code>,在里面实现自己的逻辑</li>
<li>自定义 下载失败dialog ,重写<code>showFailDialog</code>，实现自己的逻辑</li>
<li>强制更新。如果使用默认的版本dialog，<code>setCancelClickListner</code>回调里实现，具体用法请看demo</li>
<li>自定义 版本dialog,重写 <code>showVersionDialog()</code> ,在里面实现自己的逻辑，最后调用<code>downloadFile(url)</code>或者<code>downloadFile(url,filecallback)</code>注意不要调用父类的方法</li>
<li>除此之外还可以在定义的Activity里面监听一些下载和点击回调</li>
<li>自定义 版本dialog,重写 <code>showVersionDialog()</code> ,在里面实现自己的逻辑，最后调用<code>downloadFile(url)</code>或者<code>downloadFile(url,filecallback)</code>注意不要调用父类的方法<br />
<pre class="crayon-plain-tag">setOnDownloadSuccessListener(&lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;);

setCommitClickListener(&lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;);

setCancelClickListener(&lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;);

setOnDownloadingListener(&lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;);</pre>
</li>
</ul>
<h3>下载通知栏图标和文字替换</h3>
<p>需要自定义图标只需在mimap文件下建立<code>ic_launcher</code>图标，替换标题只需在项目xml定义<code>app_name</code>属性,还有其他一些属性替换，如下表:</p>
<table>
<thead>
<tr>
<th>属性名</th>
<th>属性值</th>
</tr>
</thead>
<tbody>
<tr>
<td>versionchecklib_confirm</td>
<td>确认</td>
</tr>
<tr>
<td>versionchecklib_cancel</td>
<td>取消</td>
</tr>
<tr>
<td>versionchecklib_retry</td>
<td>重试</td>
</tr>
<tr>
<td>versionchecklib_download_fail_retry</td>
<td>下载失败是否重试？</td>
</tr>
<tr>
<td>versionchecklib_download_finish</td>
<td>下载完成，点击安装</td>
</tr>
<tr>
<td>versionchecklib_downloading</td>
<td>正在下载中&#8230;</td>
</tr>
<tr>
<td>versionchecklib_check_new_version</td>
<td>检测到新版本</td>
</tr>
<tr>
<td>versionchecklib_download_fail</td>
<td>下载失败，点击重试</td>
</tr>
</tbody>
</table>
<p>更详细的使用请看demo<br />
<code>欢迎star和提issue</code><br />
<a href="https://github.com/AlexLiuSheng/CheckVersionLib" target="_blank">传送门</a></p>
</div>
<p>链接：http://www.jianshu.com/p/e246dd3b9c8a</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1677</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>错误：INSTALL_FAILED_VERSION_DOWNGRADE</title>
		<link>https://www.softwareace.cn/?p=1667</link>
		<comments>https://www.softwareace.cn/?p=1667#comments</comments>
		<pubDate>Tue, 18 Jul 2017 02:21:57 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[andriod]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1667</guid>
		<description><![CDATA[安卓新版本的 ADT 在安装apk的时候，会检查当前要运行的版本 AndroidManifest.xml 中的 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="color: #555555;">安卓新版本的 ADT 在安装apk的时候，会检查当前要运行的版本 AndroidManifest.xml 中的 versionCode 和手机中已经安装过的该程序的 versionCode 做对比，如果手机中的 versionCode 比较高，ADT 就会提示出错：INSTALL_FAILED_VERSION_DOWNGRADE</p>
<p style="color: #555555;">所以，解决这个问题就是修改 AndroidManifest.xml 中的 versionCode 修改大一些就可以了。</p>
<p style="color: #555555;">要么就是把手机中已经安装的包卸载掉。</p>
<p style="color: #555555;">这里只是为了说明错误原因。</p>
<p style="color: #555555;">http://blog.csdn.net/catoop/article/details/48086429</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1667</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android Hugo</title>
		<link>https://www.softwareace.cn/?p=1663</link>
		<comments>https://www.softwareace.cn/?p=1663#comments</comments>
		<pubDate>Mon, 10 Jul 2017 02:07:22 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[andriod]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1663</guid>
		<description><![CDATA[https://github.com/JakeWharton/hugo JakeWharton 大神的日志框架 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="color: #3f3f3f;"><a style="color: #0c89cf;" href="https://github.com/JakeWharton/hugo" target="_blank">https://github.com/JakeWharton/hugo</a></p>
<p style="color: #3f3f3f;">JakeWharton 大神的日志框架，用于 debug build 时显示方法的参数、返回值、运行时间。</p>
<h2 id="用法" style="font-weight: 100; color: #3f3f3f;">用法</h2>
<p style="color: #3f3f3f;">将 <code>@DebugLog</code> 注解添加到方法前即可。</p>
<p></p><pre class="crayon-plain-tag">@DebugLog
public String getName(String first, String last) {
  SystemClock.sleep(15); // Don't ever really do this!
  return first + " " + last;
}

V/Example: ⇢ getName(first="Jake", last="Wharton")
V/Example: ⇠ getName [16ms] = "Jake Wharton"</pre><p>&nbsp;</p>
<p style="color: #3f3f3f;">打印日志只会在 debug builds 发生，注解也不会在任何编译后的 class 文件出现。完全不影响非 debug builds.</p>
<h2 id="配置" style="font-weight: 100; color: #3f3f3f;">配置</h2>
<p style="color: #3f3f3f;"><a style="color: #0c89cf;" href="https://github.com/JakeWharton/hugo/blob/master/hugo-example/build.gradle" target="_blank">Example</a></p>
<p></p><pre class="crayon-plain-tag">buildscript {
  repositories {
    mavenCentral()
  }

  dependencies {
    classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
  }
}

apply plugin: 'com.android.application'
apply plugin: 'com.jakewharton.hugo'</pre><p><span style="color: #3f3f3f;">可以临时性禁用:</span></p><pre class="crayon-plain-tag">hugo {
  enabled false
}</pre><p>&nbsp;</p>
<p style="color: #3f3f3f;">也支持在运行时切换, use <code>Hugo.setEnabled(true|false)</code></p>
<h2 id="问题" style="font-weight: 100; color: #3f3f3f;">问题</h2>
<p style="color: #3f3f3f;">运行时 <a class="replace_word" style="font-weight: bold; color: #df3434;" title="Java 知识库" href="http://lib.csdn.net/base/java" target="_blank">Java</a>.lang.VerifyError 未找到解决方案，也好久没发新版本了，回头再看看吧。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1663</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5分钟教你打造一个秒开的Android App</title>
		<link>https://www.softwareace.cn/?p=1661</link>
		<comments>https://www.softwareace.cn/?p=1661#comments</comments>
		<pubDate>Mon, 10 Jul 2017 01:53:52 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[andriod]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1661</guid>
		<description><![CDATA[背景： 近日在开发过程中，发现每次点击app从桌面启动都有一个在桌面明显的等待时间，机型越低端的越明显，冷启动 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="color: #222222;"><span style="font-weight: bold;">背景：</span></p>
<p style="color: #222222;">近日在开发过程中，发现每次点击app从桌面启动都有一个在桌面明显的等待时间，机型越低端的越明显，冷启动优化看来已经势在必行，所以怒而一顿研究再解决之。话不多说先上优化前后效果图：</p>
<p style="color: #222222;">买家秀：</p>
<p style="color: #222222;"><img src="http://p1.pstatp.com/large/2c48000243b7f1409744" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">淘宝秀：</p>
<p style="color: #222222;"><img src="http://p3.pstatp.com/large/2c3b00025120a6ab050e" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;"><span style="font-weight: bold;">Android App启动流程：</span></p>
<p style="color: #222222;">俗话说要想优化好，流程不可少！关于android app启动的流程图如下：</p>
<p style="color: #222222;"><img src="http://p1.pstatp.com/large/2c3900024534d5439501" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">总结一下一个完成的冷启动app过程应该是经过：</p>
<p style="color: #222222;">Zygote Fork Proccess -&gt; Application:attachBaseContext() -&gt; Application:onCreate() -&gt; MainActiviity:onCreate()</p>
<p style="color: #222222;">这里主要是把相应的生命周期回调写出来。 因为一般大家的业务代码都是在这些函数回调中调用。</p>
<p style="color: #222222;"><span style="font-weight: bold;">App冷启动相关优化点</span></p>
<p style="color: #222222;">1. 生命周期内减少耗时操作：</p>
<p style="color: #222222;">· Application:attachBaseContext()：</p>
<p style="color: #222222;"><img src="http://p3.pstatp.com/large/2c43000294a4c19aefde" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">这个方法中一般雷区主要都在这句代码上，因为在Android 5.0（API 21) 以下会存在65535方法数分包的问题，当dex过大时会导致Application启动慢， ANR或者ClassNotFound等异常，关于分包解决和优化方案网上一堆就不在做赘述了。</p>
<p style="color: #222222;">· Application:onCreate()</p>
<p style="color: #222222;">这个方法是需要重点优化的，因为大家的第三方插件初始化一般都会放在这里，在Application初始化做繁重的东西会严重阻塞app启动（DiskIO，网络请求等）。以下是我们第三方插件初始化的耗时：</p>
<p style="color: #222222;">debug：</p>
<p style="color: #222222;"><img src="http://p1.pstatp.com/large/2c41000243aa96905c44" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">release：</p>
<p style="color: #222222;"><img src="http://p1.pstatp.com/large/2c43000294a5e7b766e5" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">这里把debug和release下的时间都贴出来，是希望大家不要重蹈覆辙。。。 因为debug模式下和release模式下一个是1000ms左右， 一个是300ms左右，误差很大，请大家一定要在release下测试数据！！！！</p>
<p style="color: #222222;">针对于解决第三方插件初始化耗时方案一般是：</p>
<p style="color: #222222;">1.SDK分优先级加载，非必要SDK由懒加载实现。</p>
<p style="color: #222222;">2.可以多线程初始化的sdk由多线程方式来进行初始化。</p>
<p style="color: #222222;">· MainActiviity:onCreate()</p>
<p style="color: #222222;">同上一样，尽量不要在此布局做一些耗时的操作或者呈现一些过于复杂的布局。在具体分析自己的app时发现onCreate中有这样一行代码：</p>
<p style="color: #222222;"><img src="http://p3.pstatp.com/large/2c3b0002511c0e4a2e4c" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">其作用是希望用户在打开时，一定能看见Splash的画面，主动延迟了1s加载。这里其实有更好的解决办法处理，则是把跳转MainPage的方法放在onResume中而不是放在onCreate中。因为Android系统中onResume一定是处于可见可交互的状态，用户一定能看见SplashActivity再去跳转，由系统生命周期决定，而不是固定的等待1s，此处优化后启动速度又提升了500ms。所以建议大家以后还是遵循生命周期去做一些事情，尽量别进行人为延迟阻塞。</p>
<p style="color: #222222;">2. 避免冷启动</p>
<p style="color: #222222;">App启动方式一般有3种：</p>
<p style="color: #222222;">· ColdStart ——冷启动：</p>
<p style="color: #222222;">此种方式最为耗时，一般是因为进程被干掉，系统需要重新fork进程进行一系列初始化。</p>
<p style="color: #222222;">· WarmStart ——暖启动</p>
<p style="color: #222222;">比ColdStart稍快，因为app的所有Activities还常驻在内存中，并没有被杀掉，所做的只是把app从后台提到前台来展示，并不需要重走初始化一系列行为，减少了对象初始化、布局加载等工作。但其行为表现与冷启动一致，是会displays a blank screen直到App渲染activity。这个blank screen后面会解释。</p>
<p style="color: #222222;">· LukeWarm Start——热启动</p>
<p style="color: #222222;">启动方式最快，类似于返回键退出应用又立即进入的那种行为。</p>
<p style="color: #222222;">优化方案：</p>
<p style="color: #222222;">既然冷启动那么慢，我们就在非用户主动kill进程或系统通知kill进程的其他情况下不再主动退出进程。那答案很简单了，就是在位于Activity栈底activity中Hook其返回键行为，保证用户点击返回键后不再退出app。在我们App里位于我们栈底的一定是我们的MainActivity，因为一系统行为都是由其向下衍生的。所以只需加入以下几句话：</p>
<p style="color: #222222;"><img src="http://p9.pstatp.com/large/2c48000243b6f21e623a" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">moveTaskToBack：作用是不再Finish到此Activity，仅仅是把它放到后台隐藏。类似于用户主动触发系统Home键的效果。在同是点击返回键优化前后的对比如下：</p>
<p style="color: #222222;">优化前：</p>
<p style="color: #222222;"><img src="http://p1.pstatp.com/large/2c48000243b832a137ee" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">优化后：</p>
<p style="color: #222222;"><img src="http://p3.pstatp.com/large/2c3900024538a720bf21" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">若图1中时间久后进程回收后优化效果会更为明显。</p>
<p style="color: #222222;">3.WindowBackGround——脱下秒开的最后一层薄丝袜</p>
<p style="color: #222222;">经过上面一顿操作后，我发现然并卵！！！启动速度是提升了，但是App一点击还是会在桌面停顿一下。哇呀~很难受~细细思考了一下，一个APP启动无论如何都是会新Fork进程，难道就是这个问题导致其在桌面上停顿一会儿？那其他app又是怎么做到秒开的呢？在AndroidDeveloper的Launch-Time Performance有这么一句话：</p>
<p style="color: #222222;"><img src="http://p1.pstatp.com/large/2c3b0002511ec363ec14" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">其实在创建App进程时，android系统会为你立即显示一个background window，然后再去创建app进程，当app完成first draw时，会立即由你的MainActivity（即默认启动的Activity）替换掉它。这里的background window就是上文WarmStart中提到的blank screen。谜底到此解开所谓的秒开原来就是视觉欺骗。。。所以说有人给你说他只是仅仅是优化生命周期内初始化代码达到秒开都是扯淡。但不得不承认这样用户体验大大的提升了，一点击launcher就渲染好一个背景图片，给用户一种已经启动的感觉，前面做的一系列优化，不过为了让用户少看一会儿系统给渲染的black window。</p>
<p style="color: #222222;">那为什么我们的APP会出现在系统桌面上停留一会，而不是渲染背景图呢？原来在项目创建时，系统会为launcherActivity默认了一个LightTheme，这样就会导致App点击启动后会白屏一段时间然后展示自己的Activity，为了解决白屏的问题把theme主题换成透明的就像下面</p>
<p style="color: #222222;"><img src="http://p9.pstatp.com/large/2c3900024535e433e675" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">但其实这样虽然解决了白屏的问题，但是就会出现上文所说的，点击后停留在桌面一会儿，直至MainActivity渲染出来。这是大部分App的做法，但并不是最佳解决方案。</p>
<p style="color: #222222;">WindowBackground最佳解决方案：</p>
<p style="color: #222222;">应该由windowBackground此属性作为你的品牌推广页或者logo页，如果你的SplashActivity完全不需要做任何初始化，只是希望有个闪屏页，完全可以由windowBackground来满足。</p>
<p style="color: #222222;">1.设置自定义带windowBackground的Theme</p>
<p style="color: #222222;"><img src="http://p3.pstatp.com/large/2c3b0002511f6535e187" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">前两行代码是设置Theme不透明并且默认渲染的背景图是我们必看影视闪屏页的图片。</p>
<p style="color: #222222;">- windowBackground：关键，主要设置你想要的背景图或者是动态自绘的drawable皆行，这个视图会在你冷启动时渲染给用户过渡看。</p>
<p style="color: #222222;">- windowFullscreen：全屏展示，免得顶部状态栏显现颜色不一致过于脱节和突兀</p>
<p style="color: #222222;">2. 为你的launcher Activity设置你的启动Theme</p>
<p style="color: #222222;"><img src="http://p1.pstatp.com/large/2c43000294a627f17017" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">3. 在Launch Activity启动后再把主题设置回自己的AppTheme</p>
<p style="color: #222222;"><img src="http://p9.pstatp.com/large/2c41000243acb68c253b" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">此时你的App就能完成秒开了！</p>
<p style="color: #222222;"><span style="font-weight: bold;">推荐测试工具</span></p>
<p style="color: #222222;">最终我们App从launcher点击到第一个Activity渲染完成总共需要时间是888ms，很吉利！</p>
<p style="color: #222222;"><img src="http://p3.pstatp.com/large/2c43000294a8e57390cc" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">· Time to full Display</p>
<p style="color: #222222;">上图的那行日志是由系统打印出来的，意思就是渲染Acitivity所需要的时间，如果是第一个Activity启动时长也是算在内的。 在Android4.4（API19）以上才会有此Log打出，在verbose级别搜索Displayed即可。不仅可以看自己的还可以看到其他APP的启动时长。</p>
<p style="color: #222222;"><img src="http://p3.pstatp.com/large/2c3900024537a483743d" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">附带一张小米4上业界各大App的冷启动时长~仅供参考~</p>
<p style="color: #222222;">· Hugo</p>
<p style="color: #222222;">执行时间打印神器，集成至项目后，只需在想要测试的地方加上注解即可：</p>
<p style="color: #222222;"><img src="http://p9.pstatp.com/large/2c390002453918f52c9b" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">可以是class级别，也可以是函数级别。如果注解是Appication类级别，还会把各大生命周期回调函数执行时间打印出来及其方便！GitHub传送门</p>
<p style="color: #222222;">效果如下：</p>
<p style="color: #222222;"><img src="http://p3.pstatp.com/large/2c41000243ad4f0a49fe" alt="5分钟教你打造一个秒开的Android App" /></p>
<p style="color: #222222;">· Stetho</p>
<p style="color: #222222;">这是非死不可出的调试神器，如果开发android这个没用过的话，你一定会觉得相见恨晚！</p>
<p style="color: #222222;">原文链接：http://www.gad.qq.com/article/detail/28915?ADTAG=gad.tg.tt</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1661</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>android 自定义 actionBar</title>
		<link>https://www.softwareace.cn/?p=1658</link>
		<comments>https://www.softwareace.cn/?p=1658#comments</comments>
		<pubDate>Thu, 15 Jun 2017 08:24:50 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[andriod]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1658</guid>
		<description><![CDATA[1.新建 compose_action_bar_layout.xml [crayon-69ef80e80612 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>1.新建 compose_action_bar_layout.xml</p><pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"&gt;

    &lt;Button
        android:id="@+id/compose_home_btn"
        style="@style/ActionMode.Button.Left"
        android:text="@string/cancel_action" /&gt;

    &lt;FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_toStartOf="@+id/compose_send_btn"
        android:layout_toEndOf="@+id/compose_home_btn"
        android:layout_marginStart="@dimen/compose_account_from_margin"
        android:layout_marginEnd="@dimen/compose_account_from_margin"
        android:layout_centerInParent="true"&gt;

        &lt;include layout="@layout/compose_from" /&gt;

    &lt;/FrameLayout&gt;


    &lt;Button
        android:id="@+id/compose_send_btn"
        style="@style/ActionMode.Button.Right"
        android:text="@string/compose_send" /&gt;

&lt;/RelativeLayout&gt;</pre><p>2.修改 AndroidManifest.xml</p><pre class="crayon-plain-tag">&lt;activity
            android:name="com.kingsoft.mail.compose.ComposeActivity"
            android:label="@string/app_name"
            android:theme="@style/ComposeTheme"
&lt;/activity&gt;</pre><p>3.修改 styles3.xml</p><pre class="crayon-plain-tag">&lt;style name="ComposeTheme" parent="@miui:Theme.Light.HidePopupArrow"&gt;
        &lt;item name="android:actionOverflowButtonStyle"&gt;@style/OverflowButtonStyle&lt;/item&gt;
        &lt;!-- &lt;item name="android:spinnerDropDownItemStyle"&gt;@style/spinnerDropDownItemStyle&lt;/item&gt;--&gt;
        &lt;item name="android:actionBarStyle"&gt;@style/miui.ActionBar&lt;/item&gt;
    &lt;/style&gt;</pre><p>4.修改 ComposeActivity.java</p><pre class="crayon-plain-tag">private void initActionBar() {
		// compose_action_bar_layout
		final ActionBar actionBar = this.getActionBar();
		if (actionBar == null) {
			return;
		}

		final LayoutInflater inflater = LayoutInflater.from(actionBar
				.getThemedContext());
		RelativeLayout ll = (RelativeLayout) inflater.inflate(
				R.layout.compose_action_bar_layout, null);
		actionBar.setCustomView(ll);
        final int mask = ActionBar.DISPLAY_SHOW_CUSTOM;
        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
                mask);
｝</pre><p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1658</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>设置actionBar 背景和字体颜色</title>
		<link>https://www.softwareace.cn/?p=1656</link>
		<comments>https://www.softwareace.cn/?p=1656#comments</comments>
		<pubDate>Thu, 15 Jun 2017 03:00:55 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[andriod]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1656</guid>
		<description><![CDATA[[crayon-69ef80e806533356085251/] &#160;]]></description>
				<content:encoded><![CDATA[<p></p><pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;resources&gt;
    &lt;style name="miui.ActionBar" parent="@miui:style/Widget.ActionBar"&gt;
        &lt;item name="android:background"&gt;@color/miui_theme_color&lt;/item&gt;
        &lt;item name="android:titleTextStyle"&gt;@style/miui.ActionBarTextStyle&lt;/item&gt;
    &lt;/style&gt;

    &lt;style name="miui.ActionBarTextStyle" parent="@miui:style/TextAppearance.WindowTitle"&gt;
        &lt;item name="android:textColor"&gt;@color/miui_actionbar_text_color&lt;/item&gt;
    &lt;/style&gt;
&lt;/resources&gt;</pre><p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1656</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android N分屏模式Activity生命周期的变化</title>
		<link>https://www.softwareace.cn/?p=1645</link>
		<comments>https://www.softwareace.cn/?p=1645#comments</comments>
		<pubDate>Tue, 23 May 2017 04:09:12 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[andriod]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1645</guid>
		<description><![CDATA[昨天Google发布了Android N Preview, balabala&#8230;. 我是用模拟器去验 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="color: #2f2f2f;">昨天Google发布了Android N Preview, balabala&#8230;.<br />
我是用模拟器去验证的, 通过长按多任务窗口(口)进入分屏模式, 这里只进行了简单的测试, 不排除通过配置哪个参数, 生命周期有了其它变化,</p>
<blockquote style="color: #2f2f2f;">
<ul>
<li>长按(口), Activity首先调用onMultiWindowChanged-&gt;onPause-&gt;onStop-&gt;onDestroy-&gt;onCreate-&gt;onStart- &gt;onResume-&gt;onPause(焦点切入到另一屏)</li>
<li>来回切焦点(onPause-&gt;onResume来回交替, 这就证明了, 如果是播放类的app, 暂停不能放在onPause里面)</li>
<li>来回拖动窗口大小当拖到1/3, 或者2/3之处, 生命周期都是销毁再重启然后再进入到onPause或者onResume(取决于是否有焦点)</li>
<li>分屏模式进入到桌面如果有焦点则调用onPause, 没有焦点则不发生生命周期的变化!</li>
<li>http://www.jianshu.com/p/ee94575fd2e2</li>
</ul>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1645</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android下各个按键对应的key code</title>
		<link>https://www.softwareace.cn/?p=1632</link>
		<comments>https://www.softwareace.cn/?p=1632#comments</comments>
		<pubDate>Wed, 19 Apr 2017 10:36:11 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[andriod]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1632</guid>
		<description><![CDATA[KEYCODE_UNKNOWN=0; KEYCODE_DPAD_CENTER=23; KEYCODE_R=46 [&#8230;]]]></description>
				<content:encoded><![CDATA[<table style="color: #000000; height: 513px;" border="0" width="783" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="xl65" width="314" height="19">KEYCODE_UNKNOWN=0;</td>
<td class="xl65" width="314">
<div>KEYCODE_DPAD_CENTER=23;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_R=46;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_MINUS=69;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_SOFT_LEFT=1;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_VOLUME_UP=24;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_S=47;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_EQUALS=70;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_SOFT_RIGHT=2;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_VOLUME_DOWN=25;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_T=48;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_LEFT_BRACKET=71;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_HOME=3;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_POWER=26;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_U=49;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_RIGHT_BRACKET=72;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_BACK=4;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_CAMERA=27;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_V=50;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_BACKSLASH=73;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_CALL=5;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_CLEAR=28;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_W=51;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_SEMICOLON=74;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_ENDCALL=6;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_A=29;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_X=52;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_APOSTROPHE=75;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_0=7;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_B=30;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_Y=53;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_SLASH=76;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_1=8;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_C=31;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_Z=54;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_AT=77;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_2=9;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_D=32;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_COMMA=55;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_NUM=78;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_3=10;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_E=33;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_PERIOD=56;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_HEADSETHOOK=79;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="38">
<div>KEYCODE_4=11;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_F=34;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_ALT_LEFT=57;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_FOCUS=80;//*Camera*focus</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_5=12;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_G=35;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_ALT_RIGHT=58;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_PLUS=81;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_6=13;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_H=36;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_SHIFT_LEFT=59;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_MENU=82;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_7=14;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_I=37;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_SHIFT_RIGHT=60;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_NOTIFICATION=83;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_8=15;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_J=38;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_TAB=61;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_SEARCH=84;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_9=16;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_K=39;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_SPACE=62;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_MEDIA_PLAY_PAUSE=85;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_STAR=17;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_L=40;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_SYM=63;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_MEDIA_STOP=86;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_POUND=18;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_M=41;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_EXPLORER=64;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_MEDIA_NEXT=87;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_DPAD_UP=19;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_N=42;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_ENVELOPE=65;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_MEDIA_PREVIOUS=88;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_DPAD_DOWN=20;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_O=43;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_ENTER=66;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_MEDIA_REWIND=89;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="38">
<div>KEYCODE_DPAD_LEFT=21;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_P=44;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_DEL=67;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_MEDIA_FAST_FORWARD=90;</div>
</td>
</tr>
<tr>
<td class="xl65" width="314" height="19">
<div>KEYCODE_DPAD_RIGHT=22;</div>
</td>
<td class="xl65" width="314">
<div>KEYCODE_Q=45;</div>
</td>
<td class="xl65" width="321">
<div>KEYCODE_GRAVE=68;</div>
</td>
<td class="xl65" width="267">
<div>KEYCODE_MUTE=91;</div>
</td>
</tr>
</tbody>
</table>
<p style="color: #000000;">
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1632</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Error:Cannot locate factory for objects of type DefaultGradleConnector, as ConnectorServiceRegistry</title>
		<link>https://www.softwareace.cn/?p=1610</link>
		<comments>https://www.softwareace.cn/?p=1610#comments</comments>
		<pubDate>Wed, 29 Mar 2017 08:55:39 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[andriod]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1610</guid>
		<description><![CDATA[AS报错处理 早上起来报这个错误,顿时间懵逼,我又没改文件怎么报这个错误,后来找到了解决办法 [crayon- [&#8230;]]]></description>
				<content:encoded><![CDATA[<h1 id="as报错处理" style="font-weight: 100; color: #555555;">AS报错处理</h1>
<p style="color: #555555;">早上起来报这个错误,顿时间懵逼,我又没改文件怎么报这个错误,后来找到了解决办法</p>
<p></p><pre class="crayon-plain-tag">Gradle 'MyApp' refresh failed.

Error:Cannot locate factory for objects of type DefaultGradleConnector, as ConnectorServiceRegistry has been closed.</pre><p>&nbsp;</p>
<h1 id="解决方法" style="font-weight: 100; color: #555555;"><a style="color: #0c89cf;" name="t1"></a>解决方法</h1>
<p style="color: #555555;"><img title="" src="http://img.blog.csdn.net/20160708090530853" alt="这里写图片描述" /></p>
<p style="color: #555555;">点击清理后!立马解决问题.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1610</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
