客戶端架構(gòu)設(shè)計
客戶端設(shè)計 目的是整體設(shè)計客戶端App瘫里,架構(gòu)上打好鋪墊.
Android客戶端架構(gòu)設(shè)計
主要從以下幾個方面進(jìn)行設(shè)計:MVP設(shè)計風(fēng)格沐兵、整體架構(gòu)依沮、日志系統(tǒng)茧球、網(wǎng)絡(luò)系統(tǒng)庭瑰、本地存儲、Test模塊.
MVP設(shè)計風(fēng)格
MVP即“Model —— Presenter —— View”抢埋,應(yīng)用在Android中可以實(shí)現(xiàn)Activity和業(yè)務(wù)邏輯的解耦弹灭,簡化Activity的規(guī)模【韭ⅲ現(xiàn)在Gitbub上暫時沒有合適的通用的MVP框架穷吮,我們可以基于Gitbub: Android MVP Demo 開源項(xiàng)目實(shí)現(xiàn)MVP模式。也可參考MVP開源項(xiàng)目Simple_news: MVP新聞客戶端饥努。
基本原理:
View:接口捡鱼,聲明所有的View相關(guān)的操作,包括GetValue酷愧、SetValue驾诈、Progress、Navigator等溶浴。MVP思想的核心乍迄,通過提取View接口,實(shí)現(xiàn)了Activity和Presenter的解耦戳葵。
Activity: View接口的實(shí)現(xiàn)就乓,初始化界面,初始化View中的控件拱烁,調(diào)用Presenter完成業(yè)務(wù)邏輯
Model:涉及到的數(shù)據(jù)對象,以及對數(shù)據(jù)的操作噩翠,比如可以把IO操作放到Model層
Presenter:業(yè)務(wù)邏輯的實(shí)現(xiàn)戏自,業(yè)務(wù)邏輯處理完成之后通過View接口操作UI,作用的數(shù)據(jù)是Model.
整體架構(gòu)
依賴注入型框架:
-- Dagger
阿里手淘項(xiàng)目推薦使用
項(xiàng)目地址:https://github.com/square/dagger
原理剖析文檔:http://square.github.io/dagger/
-- ButterKnife
視圖注入型框架
項(xiàng)目地址:https://github.com/JakeWharton/butterknife
文檔介紹:http://jakewharton.github.io/butterknife/
Butterknife的具體用法參考文檔說明伤锚,這里簡單介紹其特性擅笔。
- 支持Activity的View注入,比如簡化Activity中的findViewById()
- 支持View中的View注入屯援,比如簡化View.findViewById()
- 支持View的事件回調(diào)
注入示例代碼如下,更多注入示例請參考文檔:
public class ExampleActivity extends Activity {
@Bind(R.id.title) TextView title;
@Bind(R.id.subtitle) TextView subtitle;
@Bind(R.id.footer) TextView footer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.bind(this);
// TODO Use fields...
}
@OnClick(R.id.submit)
public void submit(View view) {
// TODO submit data to server...
}
@OnClick(R.id.submit)
public void sayHi(Button button) {
button.setText("Hello!");
}
}
日志系統(tǒng)
日志系統(tǒng)要完成以下幾個功能:
Debug時的日志需求
日志寫入文件的需求猛们,方便上線查看
日志上報
日志加密
系統(tǒng)日志監(jiān)控:日志奔潰信息監(jiān)控
修改醫(yī)行者中的日志系統(tǒng)可以達(dá)到需求, 也可以修改Github開源項(xiàng)目格式化日志輸出項(xiàng)目: Logger 和 日志收集項(xiàng)目:Log 達(dá)到要求。
網(wǎng)絡(luò)系統(tǒng)
OkHttp封裝:HttpGet狞洋、HttpPost弯淘、File Upload,OKHttp的使用要求創(chuàng)建Request吉懊,填寫RequestBody庐橙。參照醫(yī)行者M(jìn)essaage的封裝形式假勿,將創(chuàng)建Request的過程進(jìn)行封裝,由最簡單的請求信息和回調(diào)接口構(gòu)成一個Message态鳖,并對Message進(jìn)行統(tǒng)一處理转培。
本地存儲
本地存儲要解決的問題:
數(shù)據(jù)庫存儲
數(shù)據(jù)庫的版本管理:版本升級、數(shù)據(jù)遷移等
參考:Hibernate的ORM思想
第三方框架:
-- GreenDAO
Android Sqlite orm 的 db 工具類
項(xiàng)目地址:https://github.com/greenrobot/greenDAO
文檔介紹:http://greendao-orm.com/documentation/
官網(wǎng)網(wǎng)址:http://greendao-orm.com/
GreenDao使用方式
創(chuàng)建 "Green Dao Generation Project" 來生成 entities and core classes( DaoMaster, DaoSession .etc);
在Android Project中使用生成的Dao浆竭,
GreenDao生成:
public class ExampleDaoGenerator {
public static void main(String[] args) throws Exception {浸须、
// 這兩個參數(shù)是:數(shù)據(jù)庫版本號和schema名稱
Schema schema = new Schema(1000, "de.greenrobot.daoexample");
addNote(schema);
//addCustomerOrder(schema);
// 生成類,同時可以指定java文件位置
new DaoGenerator().generateAll(schema, "../DaoExample/src/main/java");
}
private static void addNote(Schema schema) {
Entity note = schema.addEntity("Note");
note.addIdProperty();
note.addStringProperty("text").notNull();
note.addStringProperty("comment");
note.addDateProperty("date");
}
}
- 針對版本升級的問題邦泄,GreenDao也有合適的解決方式:
數(shù)據(jù)庫版本升級問題:
/** WARNING: Drops all table on Upgrade! Use only during development. */
public static class DevOpenHelper extends OpenHelper {
public DevOpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
//dropAllTables(db, true);
//onCreate(db);
// to do update database
}
Android Project和Java Generate整合可參考: 整合
以上是從官方文檔上大致看下來的結(jié)果羽戒,該開源項(xiàng)目在業(yè)界評價甚高,使用的人也不在少數(shù)虎韵。
Test模塊
Android單元測試
-- robolectric
項(xiàng)目地址:https://github.com/robolectric/robolectric
Demo 地址:https://github.com/robolectric/robolectricsample
特點(diǎn):(1). 不需要模擬器在一般 JVM 就可以運(yùn)行測試用例(該框架在Java層實(shí)現(xiàn)了一套接口模擬Android易稠,所以可以直接在JVM上跑Android Unit Test)
(2). 能完成在真機(jī)上的大部分測試包括感應(yīng)器
其他的測試用例及相關(guān)模塊 Mock 可見:android-mock, mockito, easy-mock
robolectric
舉個例子:
Andorid中的代碼
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView)findViewById(R.id.textView1);
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
});
}
}
對應(yīng)的測試類,MainActivityTest的代碼:
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class MainActivityTest {
@Test
public void testMainActivity() {
MainActivity mainActivity = Robolectric.setupActivity(MainActivity.class);
mainActivity.findViewById(R.id.textView1).performClick();
Intent expectedIntent = new Intent(mainActivity, SecondActivity.class);
ShadowActivity shadowActivity = Shadows.shadowOf(mainActivity);
Intent actualIntent = shadowActivity.getNextStartedActivity();
Assert.assertEquals(expectedIntent, actualIntent);
}
}
-- Monkey
Monkey是Android中的一個命令行工具包蓝,可以運(yùn)行在模擬器里或?qū)嶋H設(shè)備中驶社,基于adb shell命令還控制程序包進(jìn)行測試。它向系統(tǒng)發(fā)送偽隨機(jī)的用戶事件流(如按鍵輸入测萎、觸摸屏輸入亡电、手勢輸入等),實(shí)現(xiàn)對正在開發(fā)的應(yīng)用程序進(jìn)行壓力測試硅瞧。Monkey測試是一種為了測試軟件的穩(wěn)定性份乒、健壯性的快速有效的方法。Monkey測試對象是應(yīng)用程序包腕唧。
Monkey測試的步驟:
1或辖、#adb shell
2、#monkey -p com.android.calculator2 -v 500 (-p packageName -v LogLevel 500即偽隨機(jī)事件個數(shù))
更多地命令組合和參數(shù)可以查看:
Google Monkey官網(wǎng):http://developer.android.com/tools/help/monkey.html
Android-Monkey-Test:http://ihongqiqu.com/2015/12/24/Android-Monkey-Test/
第三方測試工具
-- Tencent APT
APT 是騰訊開源的一個 Android 平臺高效性能測試組件枣接,提供豐富實(shí)用的功能颂暇,適用于開發(fā)自測、定位性能瓶頸但惶;測試人員完成性能基準(zhǔn)測試耳鸯、競品對比測試
項(xiàng)目地址:https://github.com/stormzhang/APT
以上作為參考,后續(xù)還將繼續(xù)完善膀曾。