Android开发实践小结
DaveGandy
9年前
<p>作为一名搬运工,应该懂得避免重复创建轮子。</p> <p><strong>配置keystore密码信息</strong></p> <p>通常在 <strong>app/build.gradle</strong> 中我们会使用以下方式配置:</p> <pre> <code class="language-java">signingConfigs { release { storeFile file("myapp.keystore") storePassword "mystorepassword" keyAlias "mykeyAlias" keyPassword "mykeypassword" } } </code></pre> <p>但这种方法不是特别好,因为如果你把代码分享到 github ,你的密码就泄露了。</p> <p>推荐的做法应该是在Androd项目中 <strong>gradle.properties</strong> (如果没有则手动创建一个)文件中创建以下变量,这个文件是不会被版本控制系统提交的,所以不用担心密码泄露。</p> <pre> <code class="language-java">KEYSTORE_PASSWORD=mystorepassword KEY_PASSWORD=mykeypassword</code></pre> <p>那么在 <strong>app/build.gradle</strong> 中的配置就应该是</p> <pre> <code class="language-java">signingConfigs { release { try { storeFile file("myapp.keystore") storePassword KEYSTORE_PASSWORD keyAlias "mykeyAlias" keyPassword KEY_PASSWORD } catch (ex) { throw new InvalidUserDataException("You should define KEYSTORE_PASSWORD and KEY_PASSWORD in gradle.properties.") } } } </code></pre> <p>这里在打包的时候,如果没有在 <strong>gradle.properties</strong> 配置相关变量,那么就会在messages窗口中提示</p> <pre> <code class="language-java">Error:(16, 0) You should define KEYSTORE_PASSWORD and KEY_PASSWORD in gradle.properties.</code></pre> <p><strong>包引用尽可能使用dependency而不是直接导入jar包</strong></p> <pre> <code class="language-java">dependencies { compile 'com.squareup.retrofit2:retrofit:2.1.0' }</code></pre> <p>以下方式也是不推荐使用的</p> <pre> <code class="language-java">dependencies { compile 'com.squareup.retrofit2:retrofit:2.1.0+' }</code></pre> <p>这种方式每次编译时都会去联网检测最新的包,影响性能,还可能会下载跟你不符合需求的jar包。</p> <p><strong>为release版本和debug版本指定不同的包名</strong></p> <p>同一个应用而不同的包名可以同时安装在同一个手机里面。</p> <p>可以参考以下配置</p> <pre> <code class="language-java">android { buildTypes { debug { applicationIdSuffix '.debug' versionNameSuffix '-DEBUG' } release { // ... } } }</code></pre> <p>分别为包名和版本号加上 <strong>debug</strong> 和 <strong>DEBUG</strong> 后缀。</p> <p>如果想要在版本号添加时间信息,有利于区分,可以这样处理:</p> <p>1、首先在 <strong>app/build.gralde</strong> 中定义一个 <strong>buildTime()</strong> 函数</p> <pre> <code class="language-java">//定义build 时间 def buildTime() { Date date = new Date() String build = date.format("yyMMddHHmm", TimeZone.getDefault()) return build } </code></pre> <p>2、然后再修改 <strong>versionNameSuffix</strong> 参数 </p> <pre> <code class="language-java">buildTypes { debug { //配置这包名后缀下可以同时安装release包和debug包 applicationIdSuffix ".debug" //配置versionName后缀 versionNameSuffix '_' + (buildTime()) + '-DEBUG' ... } release { ... } } </code></pre> <p>在debug包中定义了版本号</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/2054678dab457133b2a9b3d1b59f1551.png"></p> <h3><strong>开发调试工具</strong></h3> <p><strong>Stetho</strong></p> <p>Stetho是非死book开源的Android调试工具,可以使用Chrome开发工具来对Android应用进行调试、抓包、查看Sqlite数据库等功能。可以在 <strong>debug</strong> 版本中集成 Stetho ,方便开发调试。</p> <p>集成Stetho也是非常简单,只需要在 <strong>app/build.gradle</strong> 中配置</p> <pre> <code class="language-java">dependencies { compile 'com.非死book.stetho:stetho:1.4.1' } </code></pre> <p>然后在 <strong>Application</strong> 里面初始化Stetho</p> <pre> <code class="language-java">public class MyApplication extends Application { public void onCreate() { super.onCreate(); Stetho.initializeWithDefaults(this); } } </code></pre> <p>这样就配置好了,AS连接手机跑起来后。打开Chrome,在地址栏输入</p> <pre> <code class="language-java">chrome://inspect/#devices </code></pre> <p>这时候就看到手机调试的信息</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/2f9c16f19367fa98f96b96b26b439609.png"></p> <p>查看设备</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/fac7b4ff155e8babc3e1d9e8f1c834aa.png"></p> <p>查看sqlite数据库</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/8f594f672d91eecb6e4837f5b02c9377.png"></p> <p>View Hierarchy</p> <p><strong>调试网络</strong></p> <p>目前Steho支持okhttp网络库,同样的在gradle里面配置</p> <pre> <code class="language-java">dependencies { compile 'com.非死book.stetho:stetho:1.4.1' compile 'com.非死book.stetho:stetho-okhttp3:1.4.1' compile 'com.非死book.stetho:stetho-urlconnection:1.4.1' } </code></pre> <p>对OkHttp2.x版本</p> <pre> <code class="language-java">OkHttpClient client = new OkHttpClient(); client.networkInterceptors().add(new StethoInterceptor()); </code></pre> <p>对OkHttp3.x版本</p> <pre> <code class="language-java">new OkHttpClient.Builder() .addNetworkInterceptor(new StethoInterceptor()) .build(); </code></pre> <p>对于其他网络需要修改Stetho现在还没有支持,如果是 <strong>HttpURLConnection</strong> ,可以使用 <strong>StethoURLConnectionManager</strong> 来集成,详情可以参考 <a href="/misc/goto?guid=4958867210220623934" rel="nofollow,noindex">Steho</a> 官网。</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/67a03dc8ff2b647dc4f637c5250a3e00.png"></p> <p>网络抓包</p> <p><strong>LeakCanary</strong></p> <p>LeakCanary可以在应用运行时检测应用是否有OOM风险的一个工具库。同样的可只在 <strong>debug</strong> 版本中集成。</p> <p>在app/build.gradle中</p> <pre> <code class="language-java">dependencies { debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' } </code></pre> <p>在Application中</p> <pre> <code class="language-java">public class ExampleApplication extends Application { @Override public void onCreate() { super.onCreate(); if (LeakCanary.isInAnalyzerProcess(this)) { // This process is dedicated to LeakCanary for heap analysis. // You should not init your app in this process. return; } LeakCanary.install(this); // Normal app init code... } } </code></pre> <p>这样就配置好了。连接手机AS跑完后就会在手机桌面上生成一个 <strong>LeakCanary</strong> 图标,点击进入可以方便查看变量在内存中的引用链。如果 <strong>LeakCanary</strong> 检测到有内存泄露,也会发送一个通知栏消息来提醒。</p> <p><strong>AS常用插件</strong></p> <p>很多App都会使用UI注解框架来初始化UI控件其中最有名的估计就是 ButterKnife 了。</p> <pre> <code class="language-java">class ExampleActivity extends Activity { @BindView(R.id.user) EditText username; @BindView(R.id.pass) EditText password; @BindString(R.string.login_error) String loginErrorMessage; @OnClick(R.id.submit) void submit() { // TODO call server... } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); ButterKnife.bind(this); // TODO Use fields... } } </code></pre> <p>但是经常写 <strong>@BindView</strong> 也是一件令人枯燥和烦恼的事情。</p> <p><strong>Android Butterknife Zelezny</strong></p> <p>这个插件可以极大的解放程序猿的双手,提高搬砖效率。</p> <p>安装好插件后,把光标定位到 <strong>layout</strong> 文件的引用处,例如 setContentView(R.layout.simple_activity); 的 <strong>R.layout.simple_activity</strong> 末尾处,按下快捷键command+N(windows是Altt+Insert)将弹出以下对话框。</p> <p><img src="https://simg.open-open.com/show/770d9afe2ad28b320831acd3209439e1.png"></p> <p><img src="https://simg.open-open.com/show/1f18a91a0c61b1d65c8ec32e426659d2.png"></p> <p> </p> <p> </p> <p> </p> <p>来自:http://www.cnblogs.com/angrycode/p/6044351.html</p> <p> </p>