android應用開發MVC框架(二)
介紹
之前寫過一篇 android應用開發MVC框架(一) ,裡面也有簡單介紹了mvc是什麼,如果不瞭解的童鞋可以看一下。本文是另外一種實現方式,也是基於介面回撥的思想實現的一種方式,我自己在開發中比較喜歡用這種方式開發,因為這種架構可以讓專案結構變得比較清晰。還是老習慣,通過一個簡單得不能再簡單得demo來演示,我覺得我分享的是一種思想、一種方式,喜歡的可以看看,也可以在這個基礎上繼續改進,交流學習。不喜勿噴哦。有問題可以評論提出來,畢竟都是在學習中。以後還會繼續研究應用框架的搭建的。
首先看一下專案結構圖:
這裡簡單說明一下,一般應用開發都會按照模組分開,這裡也是,本demo是模擬一個很簡單得新聞獲取功能(就一個模組),news包就是新聞模組,GetNewsBusiness.java 就是新聞模組的業務處理層,GetNewsController.java 是新聞模組的控制層,而資料展示就在ui包裡面;model包是放實體類,也就是常說的bean;common裡面放的是一些通用的。
下面通過程式碼對每個類做下解釋:
CallBackInterface.java
回撥介面,裡面的方法在需要回調的地方實現此介面,然後將其作為引數傳到有資料回撥的地方去。這裡是在業務層有資料回撥,控制層實現回撥介面拿到資料之後通過handler將資料傳給activity。
package com.kroc.controller; /** * @author 林楷鵬 * @描述 回撥函式介面 */ public interface CallBackInterface { /** * 返回回撥結果 * @param key 狀態值 * @param param 可變引數 */ public void displayResult(int key, Object...param); }
News.java
新聞實體類
package com.kroc.model; public class News { private String title; private String content; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "News [title=" + title + ", content=" + content + "]"; } }
GetNewsBusiness.java
這裡是業務處理層,可以看到不同的建構函式可以實現不同引數的傳入。然後核心是在getNews方法當中,這裡是開啟一個子執行緒執行耗時操作,以免阻塞主執行緒,在程式碼當中可以看到,方法傳入了我們上面所定義的介面作為引數,這裡可以將我們獲取的結果回調回去,這裡有一個好處很明顯,就是回調當中,你可以根據訪問結果的不同(成功或者失敗或者超時等等),設定回撥狀態和回撥資料,然後等下在activity作相應處理,詳細見下面MainActivity.java
package com.kroc.news;
import android.content.ContentValues;
import com.kroc.common.Constants;
import com.kroc.controller.CallBackInterface;
import com.kroc.model.News;
/**
*
* @author 林楷鵬
* @描述: 獲取新聞業務處理層
*
*/
public class GetNewsBusiness {
public GetNewsBusiness() {
}
public GetNewsBusiness(String url, ContentValues values) {
}
/**
* 聯網獲取新聞
* @param callBackInterface 回撥介面
*/
public void getNews(final CallBackInterface callBackInterface) {
new Thread() {
public void run() {
try {
Thread.sleep(5 * 1000);//模擬5秒訪問網路
News news = new News();
news.setTitle("這裡是標題");
news.setContent("contentcontentcontentcontent");
//訪問成功,將結果回撥
callBackInterface.displayResult(Constants.SUCCESS, news);
} catch (InterruptedException e) {
//發生錯誤,回撥異常資訊
callBackInterface.displayResult(Constants.FAIL, "異常:"+e.getMessage());
}
}
}.start();
}
}
GetNewsController.java
這裡 GetNewsController + activity 充當的是控制層,控制層的存在是可以進一步將構架的耦合性降低,起到一個橋樑作用,在這裡將業務層得到的資料返回到activity當中去,如果寫得規範,設計得合理一些的話,可以多個模組使用同一個控制層的。程式碼當中可以看到,我們在這裡實現回撥介面,並在介面中的方法裡面接收資料,並將資料裝進message當中發回到activity中。而這裡再擴充套件一下,就是下面註釋掉的那個map,實際應用當中,如果你的資料變化不會很大的話,可以根據實際情況引入快取機制,增加效率,就不用每次都聯網獲取資料。
package com.kroc.news;
import android.content.ContentValues;
import android.os.Handler;
import android.os.Message;
import com.kroc.controller.CallBackInterface;
/**
*
* @author 林楷鵬
* @描述: 獲取新聞控制層
*
*/
public class GetNewsController {
private GetNewsBusiness business;
private Handler handler;
// private HashMap<String, GetNewsBusiness> map;//這裡可以加入快取機制等等,按需求
public GetNewsController() {
business = new GetNewsBusiness();
}
public GetNewsController(String url, ContentValues values) {
business = new GetNewsBusiness(url, values);
}
/**
* 獲取訪問結果
* @param handler
*/
public void getResult(Handler handler){
this.handler = handler;
business.getNews(callBackInterface);
}
//實現回撥介面
private CallBackInterface callBackInterface = new CallBackInterface() {
@Override
public void displayResult(int key, Object... param) {
Message msg = new Message();
msg.what = key;
msg.obj = param[0];//這裡注意,要param[0],因為可變引數是個陣列
handler.sendMessage(msg);
}
};
}
MainActivity.java
這裡就是activity了,也屬於 controller 層,可以將得到的資料交給 View 展示出來,在這裡實現handler,然後在handler當中獲取到資料,再將資料展示出來。
package com.kroc.ui;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import com.kroc.common.Constants;
import com.kroc.model.News;
import com.kroc.news.GetNewsController;
public class MainActivity extends Activity {
private Button get_news_btn;
private ProgressDialog progress;
private TextView show_txtv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView(){
get_news_btn = (Button)findViewById(R.id.get_news_btn);
get_news_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
progress = new ProgressDialog(MainActivity.this);
progress.setTitle("獲取新聞");
progress.setMessage("正在載入...");
progress.show();
GetNewsController controller = new GetNewsController();
controller.getResult(handler);
}
});
show_txtv = (TextView)findViewById(R.id.news_txtv);
}
//處理結果、更新介面
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
progress.dismiss();
//在這個裡面可以處理回撥的結果
switch (msg.what) {
case Constants.SUCCESS:
News news = (News)msg.obj;
show_txtv.setText(news.toString());//顯示結果
break;
case Constants.FAIL:
//處理失敗結果
show_txtv.setText(msg.obj.toString());//如果錯誤,將錯誤資訊顯示
break;
}
};
};
}
View 就是各種 xml ,這裡就不詳細介紹。
好了,基本就是這樣簡單介紹。如果有興趣或疑問的,可以留下評論。也可以下載程式碼看看。不好之處還望指出,噠噠。
最後再來兩張簡單得不能再簡單得效果圖,說明這個demo是跑得通的,哈哈。