淺談Java回撥機制
阿新 • • 發佈:2019-01-22
回撥機制讓我們程式碼執行更加高效,也讓我們程式碼變得非常的簡潔明瞭!
首先我們用個案例來一步一步帶入,當我們需要解析一段JSON字串時大部分我們的操作就是:
public class ParseJSON{
private Entity parse(String json){
*******解析部分省略*****
return entity;
}
}
我們要在呼叫時就會是:
public TActivity extends BaseActivity(){ private ParseJSON parseJSON; private String json = "Your JSON String"; private Entity entity; @Override protected void onCreate(Bundle savedInstanceState) { parseJSON = new ParseJSON(); entity = parseJSON.parse(json); } }
假設當我們的JSON足夠複雜,解析過程要3秒:
public class ParseJSON{
private Entity parse(String json){
*******解析部分省略*****
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return entity;
}
}
這樣就會阻塞我們的主執行緒,然後有的同學就會說我們用新的子執行緒:
public class ParseJSON{ private Entity parse(String json){ *******解析部分省略***** new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return entity; } }).start(); } }
這樣的話我們第一次返回的是null,而第二次才會返回解析的結果
原因:因為第一次請求得到的是還未賦值的空的物件,而第二次得到的是第一次解析後,賦給entity的值!
這就是開啟非同步請求獲取資料。
這時候我們就可以考慮使用回撥機制了,修改一下程式碼:
public class ParseJSON{ private Entity parse(String json){ *******解析部分省略***** new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //解析完再傳回Activity Activity.onParseEnd(entity); } }).start(); return entity; } } public TActivity extends BaseActivity(){ private ParseJSON parseJSON; private String json = "Your JSON String"; private Entity entity; @Override protected void onCreate(Bundle savedInstanceState) { parseJSON = new ParseJSON(); } public void onParseEnd(Entity entity){ this.entity = entity; } }
上面就回調了Activity的方法,但是當我們解析出現錯誤時,如何通知Activity呢?
這時候我們可以用面向介面程式設計的思路來設計:
public interface OnParseListener{
void onParseEnd(Entity entity);
void onParseFail();
}
public class ParseJSON{
private parse(String json,final OnParseListener parseListener){
*******解析部分省略*****
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try{
parseListener.onParseEnd(entity);
}catch(Exception e){
parseListener.onParseFail();
}
}
});
}
}
這樣只有需要parse()方法的地方,實現OnParseListener介面就可以呼叫這個方法了
通過監聽回撥的形式進行解耦
public TActivity extends BaseActivity() implements OnParseListener{
private ParseJSON parseJSON;
private String json = "Your JSON String";
private Entity entity;
@Override
protected void onCreate(Bundle savedInstanceState) {
parseJSON = new ParseJSON();
parseJSON.parse(json,this);
}
@Override
public void onParseEnd(Entity entity){
this.entity = entity;
}
@Override
public void onParseFail(){
Log.e("parse fail","..");
}
}
我們還可以像寫onClick事件一樣,新增一個set方法即可:
public class ParseJSON{
private OnParseListener parseListener;
public void setOnParseListener(OnParseListener parseListener){
this.parseListener = parseListener;
}
private parse(String json){
*******解析部分省略*****
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try{
parseListener.onParseEnd(entity);
}catch(Exception e){
parseListener.onParseFail();
}
}
});
}
}
public TActivity extends BaseActivity() implements OnParseListener{
private ParseJSON parseJSON;
private String json = "Your JSON String";
private Entity entity;
@Override
protected void onCreate(Bundle savedInstanceState) {
parseJSON = new ParseJSON();
parseJSON.setOnParseListener(new OnParseListener{
@Override
public void onParseEnd(Entity entity){
entity = entity;
}
@Override
public void onParseFail(){
Log.e("parse fail","..");
}
});
parseJSON.parse(json,this);
}
}
到這裡,我們的回撥機制就講完了,相信大家也有所有了解。
是不是覺得回撥機制讓程式碼變得更加效率簡潔了?那就get起來吧!
歡迎大家留言!