这里讲解了两种大家可以在学习Android中容易对接口迷茫的两种用法
1.用于回调
我们会在子线程中执行耗时操作,就可以用接口进行耗时操作结果的回调;
首先定义一个接口
public interface OnNetInfoCallback {
//获取信息成功
void onSuccess(String info);
//获取信息失败
void onFailure();
}
在该类中我们进行模拟耗时操作,用接口进行结果的回调
第一种写法:
可以看到在该类中定义了接口的实例,然后给其赋值,最后在getInfo方法中,用这个接口进行了结果的回调
public class InfoService {
private OnNetInfoCallback onNetInfoCallback;
public void setOnNetInfoCallback(OnNetInfoCallback onInfoFetchCallback) {
this.onNetInfoCallback = onInfoFetchCallback;
}
public void getInfo() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
onNetInfoCallback.onSuccess("" + new Date());
} catch (Exception e) {
onNetInfoCallback.onFailure();
}
}
});
thread.start();
}
}
我们在MAinActivity中,对回调的结果进行处理,并且调用getInfo让其返回结果,
button.setOnClickListener(view -> {
InfoService infoService = new InfoService();
infoService.setOnNetInfoCallback(new OnNetInfoCallback() {
@Override
public void onSuccess(String info) {
Log.e("TAG", "onSuccess: " + info );
}
@Override
public void onFailure() {
}
});
infoService.getInfo();
});
第二种写法(更简洁)
直接可以把接口就放在方法参数中
可以看到在该类中的getInfo方法中,接收了一个接口函数
public class InfoService {
public void getInfo(OnNetInfoCallback onInfoFetchCallback) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
onInfoFetchCallback.onSuccess("" + new Date());
} catch (Exception e) {
onInfoFetchCallback.onFailure();
}
}
});
thread.start();
}
}
然后我们就可以在Activity中调用了该类的方法,并传入一个接口对象,然后实现在接收到回调结果之后做什么UI操作
button.setOnClickListener(view -> {
InfoService infoService = new InfoService();
infoService.getInfo(new OnNetInfoCallback() {
@Override
public void onSuccess(String info) {
Log.e("TAG", "onSuccess: "+info );
}
@Override
public void onFailure() {
}
});
});
2.在MVP中使用
比如我现在有一个MainActivity,想要使用MVP模式,举一个最简单的例子
首先定义一个interface叫做xxxContract,可以理解为接口的集合接口
这个接口里面又包括了关于控制View变化的接口MainView 和 控制逻辑的接口MainPresenter,即常说的P层
public interface MainContract {
interface MainView{
void refreshText(String str);
}
interface MainPresenter{
void updateText(String str);
}
}
然后我们去实现具体的Presenter,在这个里面可以用于实现具体的逻辑,以及控制什么时候去调用更新UI的接口
也就是说我们的MainView中的什么时候去实现是由MainPresenter去决定的
public class MainPresenter implements MainContract.MainPresenter{
MainContract.MainView mainView;
public MainPresenter(MainContract.MainView mainView){
this.mainView = mainView;
}
@Override
public void updateText(String str) {
mainView.refreshText(str);
}
}
然后我们将MainActivity实现控制UI的接口,将this传入presenter的参数中,意味着当前MainActivity是MainView的实现类,在Persenter里面进行的操作会在MainActivity也进行
然后在其实现的接口中进行具体的UI操作即可
public class MainActivity extends AppCompatActivity implements MainContract.MainView{
private Button button;
MainPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
presenter = new MainPresenter(this);
button = findViewById(R.id.button);
button.setOnClickListener(view ->{
presenter.updateText("new string");
});
}
@Override
public void refreshText(String str) {
button.setText(str);
}
}
可能会有人说:那MVP这么麻烦,就是一个修改button字符串就写了这么多代码有什么好处?
其实MVP的好处就是将逻辑和view层分开,我们在activity写逻辑的话可能代码很乱,这里一块那里一块,代码多且乱,想改必须得全篇搞懂原有代码
而使用了MVP之后,不仅可以有接口直接表明这个方法是干嘛的,而且逻辑和UI的逻辑分离,代码不乱,想改哪一部分可以直接改。