<div class="markdown_views"> <!-- flowchart 箭頭圖標 勿刪 --> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg> <blockquote> <p>來自本身簡書博客:原文地址:<a href="https://www.jianshu.com/p/4d092c915ef1" rel="nofollow" target="_blank">https://www.jianshu.com/p/4d092c915ef1</a></p> </blockquote>java
<p>首先SDK是提供給別人調用的工具。因此常見的SDK都是以jar包,so庫,aar包等方式導入APP項目中。而後提供一些公開的API供接入方調用。因此在Androidstudio中若是須要生成jar或者aar,就須要將module變成library。</p>android
<h4 id="1androidstudio生成library">一、AndroidStudio生成library</h4>git
<p>在這裏介紹AndroidStudio兩種生成library的方式。</p>github
<h5 id="11兩種生成library的方式">1.一、兩種生成library的方式</h5>web
<h6 id="新建library-module">新建library module。</h6>api
<p><img src="https://upload-images.jianshu.io/upload_images/1930161-bba4e6334023588a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png" title=""> <br> 這種會直接生成可編譯成jar和aar的module。</p>bash
<h6 id="新建android項目而後修改app下的buildgradle">新建Android項目,而後修改app下的build.gradle</h6>markdown
<p><img src="https://upload-images.jianshu.io/upload_images/1930161-890e340522780980.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png" title=""></p>app
<p>將 <code>apply plugin: 'com.android.application'</code>修改爲<code>apply plugin: 'com.android.library'</code> <br> 而後去掉<code>applicationId "com.mg.axe.helloworld"</code>就把可運行的Android module變成了一個library module。 <br> <strong>注意:這種方式在編譯前必定要作如下事情</strong> <br> * 刪除自定義的Application和在AndroidManifest.xml的配置。 <br> * 去點入口的Activity,不然在Android Studio接入時會生成兩個圖標入口。</p>eclipse
<h5 id="11使用gradle所帶的命令編譯">1.一、使用gradle所帶的命令編譯</h5>
<p>這些命令能夠本身在控制檯使用,能夠直接點開右上角的Gradle直接使用。 <br> <img src="https://upload-images.jianshu.io/upload_images/1930161-c1bb96df76855c35.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png" title=""></p>
<ul> <li><strong>assembleRelease</strong>&<strong>assembleDebug</strong> </li> </ul>
<p><img src="https://upload-images.jianshu.io/upload_images/1930161-0ba017df99ed59d9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png" title=""> <br> 在build下的assembleRelease和assembleDebug均可以生成aar包。這邊和APP開發很類似,能夠在buildTypes下對release包作混淆等等操做。</p>
<p>若是編譯的命令執行完畢,能夠在當前module下的build文件下找到編譯好的.aar文件。 <br> <img src="https://upload-images.jianshu.io/upload_images/1930161-ae5355ade2502e4c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png" title=""> <br> 若是須要jar包,則只需將這個aar文件解壓便可。 <br> <img src="https://upload-images.jianshu.io/upload_images/1930161-91e77aff157042f2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png" title=""> <br> classes.jar就是編譯成jar的class文件。</p>
<h5 id="12aar和jar">1.二、aar和jar</h5>
<ul> <li><p>.aar是適用於AndroidStudio的接入方式,不須要過多的考慮當SDK存在界面,圖片等資源文件的狀況。解壓aar也能夠看到,aar是一個將源碼(jar)和資源文件都打包好的文件。固然也能夠在eclipse中使用,前提是eclipse須要安裝gradle編譯環境。</p></li> <li><p>jar只包含編譯好的源代碼,若是SDK包含資源文件,則須要額外導入,適用於eclipse導入;AndroidStudio也一樣適用,不過當SDK包含資源文件時,導入aar將會更方便。</p></li> </ul>
<h4 id="2兩種接入方式">二、兩種接入方式</h4>
<p>通常狀況接入方式爲AndroidStudio和Eclipse。其餘的接入方式就不考慮了,可能大同小異,最主要的是其餘的接入方式我也不會。 <br> <img src="https://upload-images.jianshu.io/upload_images/1930161-aee57be922bc3c13.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="手動滑稽" title=""></p>
<h5 id="21androidstudio接入方式">2.一、AndroidStudio接入方式</h5>
<p>這裏只介紹.aar的接入方式,AndroidStudio接入jar方式就不作介紹。 <br> * 將.aar文件複製到項目的libs中。 <br> * 並在app下的build.gradle中的android中添加以下代碼 </p>
<pre class="prettyprint" name="code"><code class="hljs bash has-numbering">repositories{ flatDir { <span class="hljs-built_in">dirs</span> <span class="hljs-string">'libs'</span> } }</code></pre>
<ul> <li>在dependencies中添加依賴的代碼</li> </ul>
<pre class="prettyprint" name="code"><code class="hljs bash has-numbering"> // implementation(name: <span class="hljs-string">'aar包的名字'</span>, ext: <span class="hljs-string">'aar'</span>) implementation(name: <span class="hljs-string">'game_sdk'</span>, ext: <span class="hljs-string">'aar'</span>)</code></pre>
<p>而後點擊同步(Sync Now),就成功的將.arr導入項目了。</p>
<p>能夠在External Libraries中找到導入的aar依賴。 <br> <img src="https://upload-images.jianshu.io/upload_images/1930161-9014cf4f859fa5a1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png" title=""></p>
<p><img src="https://upload-images.jianshu.io/upload_images/1930161-2224b0905f66ad49.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png" title=""> <br> 點開aar,能夠看(源代碼)jar和(資源文件)res。</p>
<h5 id="22eclipse接入方式">2.二、Eclipse接入方式</h5>
<p>eclipse通常是接入jar包的方式接入SDK,當SDK存在界面、資源文件時,接入方式比AndroidStudio接入aar稍微麻煩點,須要將jar包和資源文件分開導入。 <br> * 解壓aar文件。 <br> * 將jar包複製到libs文件加下,並添加依賴(add to path) 。 <br> * 若是有資源文件,則須要將res下的資源文件複製到項目對應的位置。 <br> * 若是SDK用到了Activity等組件,還需去註冊等,這些都應在SDK接入文檔中指明清楚。</p>
<h5 id="23兩種接入方式都須要注意的問題">2.三、兩種接入方式都須要注意的問題</h5>
<p>在SDK中聲明的權限,制定的Android版本範圍等都要在SDK接入文檔中指明清楚。</p>
<h4 id="3可能踩的坑">三、可能踩的坑</h4>
<h5 id="31資源文件沒法獲取的問題">3.一、資源文件沒法獲取的問題。</h5>
<p>若是編譯好的jar中使用了資源文件,而後使用了R.xx.xx這樣的代碼,可能會出現這樣的異常。</p>
<pre class="prettyprint" name="code"><code class="hljs http has-numbering"><span class="hljs-attribute">java.lang.NoClassDefFoundError</span>: <span class="hljs-string">Failed resolution of: Lcom/ysyc/axechen/R$id</span></code></pre>
<p>找不到id。最後是參照開源的TypeSDK才解決了這個問題。經過以下的方法去尋找id。</p>
<pre class="prettyprint" name="code"><code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> GetResId { <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getId</span>(Context context, String paramString1, String paramString2) { <span class="hljs-keyword">return</span> context.getResources().getIdentifier(paramString2, paramString1, context.getPackageName()); } }</code></pre>
<p>加載佈局和控件的方法:</p>
<pre class="prettyprint" name="code"><code class="hljs cs has-numbering"><span class="hljs-comment">// 獲取佈局id</span> GetResId.getId(<span class="hljs-keyword">this</span>, <span class="hljs-string">"layout"</span>, <span class="hljs-string">"activity_main"</span>) <span class="hljs-comment">// 獲取控件id</span> GetResId.getId(<span class="hljs-keyword">this</span>, <span class="hljs-string">"id"</span>, <span class="hljs-string">"login"</span>)</code></pre>
<h5 id="32三方包衝突問題">3.二、三方包衝突問題</h5>
<p>若是SDK用到了三方庫,而後接入方的項目中也用到了一樣的三方庫,那麼當編譯的時候就會出現類衝突,沒法編譯經過。這個時候就要求在編譯SDK時不要將三方的依賴編譯到SDK的jar中。那麼在添加依賴時須要使用compileOnly關鍵字。</p>
<pre class="prettyprint" name="code"><code class="hljs livecodeserver has-numbering">compileOnly <span class="hljs-built_in">files</span>(<span class="hljs-string">'libs/gson-2.8.5.jar'</span>)</code></pre>
<p>或者</p>
<pre class="prettyprint" name="code"><code class="hljs bash has-numbering">compileOnly <span class="hljs-string">'com.google.code.gson:gson:2.8.5'</span></code></pre>
<p>這樣纔不會將引入的依賴編譯到SDK的jar中,這個時候須要接入方導入這些依賴,固然SDK的接入文檔要詳細說明。</p>
<h5 id="33請使用最日常的api和習慣">3.三、請使用最日常的api和習慣</h5>
<p>最好不去使用一些新的特性。若是接入方沒有使用到這些特性,可能編譯沒法經過,尤爲是eclipse接入時會出現更多問題。我遇到的問題:我在編譯SDK時就是由於使用了lamada表達式致使eclipse沒法編譯經過。</p>
<h4 id="4混淆">四、混淆</h4>
<p>SDK的混淆和作app的混淆是同樣的。</p>
<pre class="prettyprint" name="code"><code class="hljs bash has-numbering"> buildTypes { release { minifyEnabled <span class="hljs-literal">true</span> proguardFiles getDefaultProguardFile(<span class="hljs-string">'proguard-android.txt'</span>), <span class="hljs-string">'proguard-rules.pro'</span> } }</code></pre>
<p>在混淆的時候,若是使用了三方庫,三方庫混淆的要求一樣須要加上混淆。 <br> <strong>若是接入方須要作混淆,請記住加上SDK的混淆要求和三方庫的混淆要求。省得SDK的代碼混淆以後又被接入方混淆致使出錯。</strong></p>
<h4 id="5關於sdk的其餘解決方案">五、關於SDK的其餘解決方案</h4>
<p>實際上,用原生的界面作SDK並非很是好的解決方案,主要是不利於SDK的更新和跨平臺。最好的方式是加載H5,更新起來更方便,SDK實現起來更簡單。</p>
<h4 id="6一些開源的sdk">六、一些開源的SDK</h4>
<p><a href="https://github.com/typesdk/TypeSDK" rel="nofollow" target="_blank">https://github.com/typesdk/TypeSDK</a> <br> <a href="https://github.com/zuowutan/ShareGameSdk" rel="nofollow" target="_blank">https://github.com/zuowutan/ShareGameSdk</a></p>
<p><strong>若是這篇文章對你有幫助,還請點個贊再走吧:)</strong></p> </div>