Callback2.0
Callback定义?
a callback is a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time.
The invocation may be immediate as in a synchronous callback or it might happen at later time, as in an asynchronous callback.
In all cases, the intention is to specify a function or subroutine as an entity that is, depending on the language, more or less similar to a variable.
不难看出callback是在一个Class中把一段代码以argument的形式发送到另外一个class中调用。
我们在android中经常用onClickListnere的Onclick()这就是一个回调方法。 学过js的人应该很明白callback因为js基本都是用callback的。
Callback实例1
//声明一个接口 public interface ICallBack { void postExec(); } //另外一个类有方法里面有个参数以是这个接口类型的 public class FooBar { private ICallBack callBack; public void setCallBack(ICallBack callBack) { this.callBack = callBack; } public void doSth() { callBack.postExec(); } }
FooBar中接收一个实现callback方法类然后调用doSth()方法时调用对用的callback方法,然后真正实现callback方法的类中就会触发并执行callback方法中的代码。
public class Test { public static void main(String[] args) { FooBar foo = new FooBar(); foo.setCallBack(new ICallBack() { public void postExec() { System.out.println("method executed."); } }); foo.doSth();//调用函数 } }
在Test,通过FooBar的setCallBack方法以参数的形式把callback方法实现类传递给FooBar,当调用foo.doSth();会触发callback()方法。
Callback实例2
学过设计模式的mvp的人应该知道callback怎么实现的。 MVP中M是具体操作类可以理解为操作DB。V是有关GUI的即View那个中间指挥者就是P。
比如说登录login。通过V我们会获取到账号密码,然后再M中验证数据账号密码是否匹配,然后重新回到V中更新UI。
package com.amap.login; import android.content.Context; public interface ILoginModel { void login(String userid, String password, Context context, OnLoginFinishedListener listener); }
package com.amap.login; import android.content.Context; public interface ILoginPresenter { void validateCredentials(String userid, String password, Context context); void onDestroy(); }
package com.amap.login; public interface ILoginView { void showProgress(); void hideProgress(); void userIdNotFoundError(); void passwordNotFoundError(); void userIdNullPointError(); void passwordNullPointError(); void onUserLoginError(); void navigateToHome(); }
我们分别定义了MVP模式中的代表M,V,P接口类。
package com.amap.login; import android.content.Context; import android.os.Handler; import android.text.TextUtils; import com.amap.bean.User; import com.amap.common.UserDataManager; public class LoginModelImpl implements ILoginModel{ private UserDataManager mUserDataManager; public static final String PREFERENCE_NAME = "UserInfo"; public static int MODE = Context.MODE_PRIVATE; public LoginModelImpl() { this.mUserDataManager = UserDataManager.getInstence(); } @Override public void login(final String userid, final String password,final Context context, final OnLoginFinishedListener listener) { new Handler().postDelayed(new Runnable() { @Override public void run() { if (TextUtils.isEmpty(userid)) { listener.onUserIdNullPointError(); return; }else if (TextUtils.isEmpty(password)) { listener.onPasswordNullPointError(); return; } //User user = mUserDataManager.findUserByAccAndPwd(username,password); User user = mUserDataManager.fetchOneUser(userid); if(user == null){ listener.onUserIdNotFoundError(); return; } else{ if (user.getPassword().equals(password)) { //if (user.getStatus().equals("1")) { // listener.onUserLoginError(); // return; //} else { user.setUserId(userid); user.setPassword(password); user.setImage(user.getImage()); user.setName(user.getName()); mUserDataManager.saveSharedPreferences(user, context); user.setStatus("1"); mUserDataManager.updateUserStatusByAcc(userid, "1"); UserDataManager.setSelf(user); listener.onSuccess(); //} } else { listener.onPasswordNotFoundError(); return; } } } }, 1000); } }
package com.amap.login; import android.content.Context; public class LoginPresenterImpl implements ILoginPresenter,OnLoginFinishedListener{ ILoginModel loginModel = null; ILoginView loginView = null; public LoginPresenterImpl(ILoginView loginView) { loginModel = new LoginModelImpl(); this.loginView = loginView; } @Override public void validateCredentials(String userid, String password, Context context) { if(loginView != null) { loginView.showProgress(); } loginModel.login(userid, password, context, this); } @Override public void onDestroy() { // TODO Auto-generated method stub } @Override public void onSuccess() { if(loginView != null) { loginView.navigateToHome(); } } @Override public void onUserIdNotFoundError() { // TODO Auto-generated method stub if(loginView != null) { loginView.userIdNotFoundError(); loginView.hideProgress(); } } @Override public void onUserIdNullPointError() { // TODO Auto-generated method stub if(loginView != null) { loginView.userIdNullPointError(); loginView.hideProgress(); } } @Override public void onPasswordNotFoundError() { // TODO Auto-generated method stub if(loginView != null) { loginView.passwordNotFoundError(); loginView.hideProgress(); } } @Override public void onPasswordNullPointError() { // TODO Auto-generated method stub if(loginView != null) { loginView.passwordNullPointError(); loginView.hideProgress(); } } @Override public void onUserLoginError() { // TODO Auto-generated method stub if(loginView != null) { loginView.onUserLoginError(); loginView.hideProgress(); } } }
package com.amap.login; public interface OnLoginFinishedListener { void onUserIdNotFoundError(); void onUserIdNullPointError(); void onPasswordNotFoundError(); void onPasswordNullPointError(); void onUserLoginError(); void onSuccess(); }
package com.amap.activity; import android.app.Activity; import android.app.Dialog; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.amap.customview.MyProgress; import com.amap.friends.R; import com.amap.login.ILoginView; import com.amap.login.LoginPresenterImpl; public class LoginActivity extends Activity implements OnClickListener,ILoginView { private EditText mAccount; private EditText mPwd; private Button button_login; private TextView user_register; private Dialog ProgressBar_login; private LoginPresenterImpl loginPresenterImpl; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initView(); initListener(); } public void initView() { setContentView(R.layout.activity_login); mAccount = (EditText) findViewById(R.id.editText_useracc); mPwd = (EditText) findViewById(R.id.editText_password); button_login = (Button) findViewById(R.id.button_login); user_register = (TextView) findViewById(R.id.user_register); ProgressBar_login = MyProgress.createLoadingDialog(this, getString(R.string.login_msg)); } public void initListener() { button_login.setOnClickListener(this); user_register.setOnClickListener(this); loginPresenterImpl = new LoginPresenterImpl(this); } public void login() { loginPresenterImpl.validateCredentials(mAccount.getText().toString() .trim(), mPwd.getText().toString().trim(), getApplicationContext()); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button_login: login(); break; case R.id.user_register: navigateToRegister(); break; default: break; } } @Override public void showProgress() { // TODO Auto-generated method stub ProgressBar_login.show(); } @Override public void hideProgress() { // TODO Auto-generated method stub ProgressBar_login.hide(); } public void navigateToRegister() { // TODO Auto-generated method stub startActivity(new Intent(this, RegisterActivity.class)); finish(); } @Override public void navigateToHome() { // TODO Auto-generated method stub startActivity(new Intent(this, MainActivity.class)); finish(); } @Override public void userIdNotFoundError() { // TODO Auto-generated method stub Toast.makeText(this, R.string.login_userid_fail, Toast.LENGTH_SHORT).show(); } @Override public void passwordNotFoundError() { // TODO Auto-generated method stub Toast.makeText(this, R.string.login_password_fail, Toast.LENGTH_SHORT).show(); } @Override public void userIdNullPointError() { // TODO Auto-generated method stub Toast.makeText(this, R.string.account_empty, Toast.LENGTH_SHORT).show(); } @Override public void passwordNullPointError() { // TODO Auto-generated method stub Toast.makeText(this, R.string.pwd_empty, Toast.LENGTH_SHORT).show(); } @Override public void onUserLoginError() { // TODO Auto-generated method stub Toast.makeText(this, R.string.login_exist, Toast.LENGTH_SHORT).show(); } }
从以上的代码可以看出callback的好处。Activity中的代码构造比较清晰易懂。
没有calback基本不知道怎么在别的class中操作以后更新UI。
有了callback可以直接在别的class中简洁的更新UI了。非常cool~~~