編輯:關於android開發
本文為原創文章,轉載請注明出處。
文章最後會附帶源碼下載地址,有需要的朋友可下載。
通常我們編寫Android APP時有這樣的需求:(1)代碼混淆;(2)模塊化;(3)向第三方提供JAR包。下面將以實例的形式向初學Android或開始使用AndroidStudio(AS)的朋友介紹下這幾部分。
引述:
(1)AS采用了Gradle的構建工具,可以讓我們很方便的對我們的APP進行配置,比如版本、支持最低API level 、代碼混淆文件、第三方庫等等,具體語法請查考其他朋友的文章。
(2)AS提供了模塊編程,便於我們對APP進行分層和理清架構,個人推薦初學者可以參考下這篇文章。
實例正文:
本文實例僅作為演示使用,重點是演示代碼混淆和打包JAR,所以功能都進行了簡化並省略了很多邏輯代碼。
基本需求:接受用戶的登錄請求,模擬完成向服務端發起登錄請求,並提示登錄結果。
一、創建項目
項目目錄結構:
個人習慣將各模塊創建為平級,模塊(android library)描述:
app:用戶模塊,用戶交互界面、用戶資源等 model:實體模塊 player:核心業務模塊 utils:輔助類模塊。
提示:創建模塊時注意模塊類型為Android Library,否則會對後面的一些功能會有影響。
二、代碼編寫
(1)model模塊
用戶登錄信息實體:
1 package xiaoshubao.model; 2 3 /** 4 * 作者: 小書包 5 * 日期: 2016/6/16 6 * 版本: V1.0 7 * 說明: 8 */ 9 public class UserModel { 10 String userName; 11 String pwd; 12 13 public void setUserName(String userName) { 14 this.userName = userName; 15 } 16 17 public void setPwd(String pwd) { 18 this.pwd = pwd; 19 } 20 21 public String getUserName() { 22 return userName; 23 } 24 25 public String getPwd() { 26 return pwd; 27 } 28 } View Code
其他實體不再貼代碼,model層最終的代碼結構如下:
HttpMsgCallback:http回調請求接口
Parent:無實際意義類,代碼混淆時需要
UserLoginCallback:用戶登錄結果回調接口
(2)utils模塊:
網絡訪問輔助類(HttpUtils):
1 package xiaoshubao.utils; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import xiaoshubao.model.HttpMsgCallback; 7 import xiaoshubao.model.Parent; 8 9 /** 10 * 作者: 小書包 11 * 日期: 2015/12/18 12 * 版本:V1.0 13 * 說明:與服務端Http通信 14 */ 15 public class HttpUtils implements Parent { 16 private static final String TAG = "HttpUtils"; 17 18 /** 19 * 發送Post請求到服務器 HTTP 20 * 21 * @param strUrlPath 服務器地址 22 * @param params 請求體參數 23 * @return 錯誤碼 24 */ 25 private static String httpPostData(String strUrlPath, Map<String, String> params) { 26 27 return "true"; 28 } 29 30 /** 31 * 向http服務器發出注冊消息 32 * @param serverUrl 服務器地址 33 * @param params 請求體參數 34 * @param httpMsgCallback 執行結果回調 35 */ 36 public static void sendPostMsgToServer(final String serverUrl, final HashMap params, final HttpMsgCallback httpMsgCallback) { 37 Thread thread = new Thread(new Runnable() { 38 @Override 39 public void run() { 40 try { 41 Thread.sleep(2*1000);//當前線程睡眠兩秒鐘模擬發送網絡請求 42 } catch (InterruptedException e) { 43 e.printStackTrace(); 44 } 45 String result = HttpUtils.httpPostData(serverUrl, params); 46 httpMsgCallback.httpPostCallBack(result); 47 } 48 }); 49 thread.start(); 50 } 51 } View Code
(3)player模塊
UserLogin類(用戶登錄業務類):
1 package xiaoshubao.player; 2 3 import java.util.HashMap; 4 5 import xiaoshubao.model.HttpMsgCallback; 6 import xiaoshubao.model.Parent; 7 import xiaoshubao.model.UserLoginCallback; 8 import xiaoshubao.model.UserModel; 9 import xiaoshubao.utils.HttpUtils; 10 11 /** 12 * 作者: 小書包 13 * 日期: 2016/6/16 14 * 版本: V1.0 15 * 說明: 16 */ 17 public class UserLogin implements Parent { 18 UserLoginCallback userLoginCallback; 19 public UserLogin(UserLoginCallback userLoginCallback){ 20 this.userLoginCallback=userLoginCallback; 21 } 22 23 /** 24 * 用戶登錄 25 * @param user 用戶信息 26 */ 27 public void login(UserModel user){ 28 userLogin(user); 29 } 30 private void userLogin(UserModel user){ 31 HashMap hashMap=new HashMap(); 32 hashMap.put("userName",user.getUserName()); 33 hashMap.put("pwd",user.getPwd()); 34 HttpUtils.sendPostMsgToServer("XXXXX", hashMap, httpMsgCallback); 35 } 36 HttpMsgCallback httpMsgCallback=new HttpMsgCallback() { 37 @Override 38 public void httpPostCallBack(String json) { 39 if (json.contains("true")&&null!=userLoginCallback){ 40 userLoginCallback.loginResult(true); 41 }else if (null!=userLoginCallback){ 42 userLoginCallback.loginResult(false); 43 } 44 } 45 }; 46 private void fun1(){} 47 private void fun2(){} 48 } View Code
三、代碼混淆
AS中進行代碼混淆需要在build.gradle文件和proguard-rules.pro文件中進行設置(可以通過jd-gui工具對比混淆前後效果):
(1)build.gradle文件
minifyEnabled:表示是否開啟混淆,默認為false
proguardFiles:混淆配置文件,一般就采用項目中默認的proguard-rules.pro文件。
(2)proguard-rules.pro文件
混淆設置,具體可參考progurad官網。
注意圖中紅框部分,因為所有jar包都要求有對外接口(沒有對外接口的模塊一般也沒什麼意義),有多種種方式設置對外接口類:
a:-keep public class *,例如:
-keep public class * {
public protected *;
}
b:如圖所示。
因為一個模塊一般有很多類文件,混淆時我們希望除對外接口類的其他所有類文件的類名也進行混淆,那麼就可以單獨創建一個基類或接口,讓對外的接口類繼承該基類或接口。
c:-keep public class XXX,特定類不混淆,例如:
-keep public class xiaoshubao.player.UserLogin{
public protected *;
}
四、打包JAR包
(1)proguard-rules.pro配置
配置生成JAR包的基本屬性,如下:
上述代碼很簡單不再敘述。
(2)生成JAR包
CMD命令行中切換到當前項目目錄下,執行gradlew makeJar 命令。
順利的話會生成JAR包,如果是第一次采用gradlew生成,可能需要在線更新相關包,大約幾分鐘時間。
如果配置、類引用出現錯誤,CMD窗口會提示,請根據具體的錯誤提示做修改。
(3)JAR包合並
gradlew makeJar命令會在model、uitls、palyer目錄下分別生成這三個模塊的JAR包,那麼如果我們需要向第三方提供SDK,三個JAR包可能會不太方便,所以就有了合並為一個JAR包的需求。
我們知道JAR包其實就是普通的壓縮包而已,所以對三個JAR包進行解壓後文件如下:
注意:META-INF配置文件,該項目對palyer、utils模塊進行了混淆而model模塊未混淆(也可通過配置進行混淆),所以只有一個META-INF文件生成,如果有多個模塊未混淆時生成了多個META-INF文件,采用本文方法進行JAR包合並會出問題。
xiaoshubao文件夾下的目錄文件如下:
一起壓縮META-INF、xiaoshubao文件生成zip文件,重命名為.jar文件,結果如下:
五、第三方使用
將MyUserManager.jar包導入測試項目(非JAR包源碼項目)中,如下:
提示:有時在JAR包前面沒有向下的三角符號也無法點開JAR包查看裡面的類文件,且使用JAR包裡的類時會報錯,此時重啟該項目應該就可以出現如上圖所示的效果。
(1)登錄界面:
(2)登錄代碼:
1 package xiaoshubao.jartest; 2 3 import android.content.Context; 4 import android.os.Bundle; 5 import android.os.Message; 6 import android.support.v7.app.AppCompatActivity; 7 import android.view.View; 8 import android.widget.EditText; 9 import android.widget.Toast; 10 11 import xiaoshubao.model.UserLoginCallback; 12 import xiaoshubao.model.UserModel; 13 import xiaoshubao.player.UserLogin; 14 15 public class MainActivity extends AppCompatActivity { 16 Context context; 17 MyHandler handler; 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.activity_main); 22 context = this; 23 handler = new MyHandler(); 24 } 25 public void btn_loginClick(View v) { 26 UserLogin userLogin = new UserLogin(userLoginCallback); 27 UserModel userModel = new UserModel(); 28 String userName = ((EditText) findViewById(R.id.etUserName)).getText().toString().trim(); 29 userModel.setUserName(userName); 30 String pwd = ((EditText) findViewById(R.id.etPwd)).getText().toString().trim(); 31 userModel.setPwd(pwd); 32 userLogin.login(userModel); 33 } 34 35 UserLoginCallback userLoginCallback = new UserLoginCallback() { 36 @Override 37 public void loginResult(boolean result) { 38 Message msg = Message.obtain(); 39 msg.what = 7634; 40 if (result) { 41 msg.obj = "登錄成功!"; 42 } else { 43 msg.obj = "登錄失敗!"; 44 } 45 handler.sendMessage(msg); 46 } 47 }; 48 49 public class MyHandler extends android.os.Handler { 50 @Override 51 public void handleMessage(Message msg) { 52 switch (msg.what) { 53 case 7634: 54 Toast.makeText(context, msg.obj.toString(), Toast.LENGTH_LONG).show(); 55 } 56 } 57 } 58 } View Code
(3)運行效果
代碼混淆是最簡單、最基礎的Android APP安全保障,後續將還會介紹其他的關於APP安全相關技術。
本實例DEMO下載地址(MyApplication4 源碼項目,JarTest模擬第三方項目)。
Android動畫效果生動有趣的通知NiftyNotification(Android Toast替代品),androidnotificationNiftyNotific
閱讀《Android 從入門到精通》(17)——進度條 進度條(ProgressBar) java.lang.Object; android.view.View; and
回調機制的實現。,回調機制實現.簡單回調機制的建立主要分為下面幾步: 1.寫一個回調類,寫出需要的構造方法 2.定義一個接口,裡面寫一個抽象方法,方法體(String d
Android定位&地圖&導航——基於百度地圖移動獲取位置和自動定位,android定位城市 一、問題描述 使用百度地圖實現如圖所示應用,首先自