介绍
我们在开发的时候,一定会遇到页面跳转,当没有登录的时候,先跳转到登录,登录成功后再跳转到目标页。如下图:
跳转到目标页.png
实现这种效果有四种方式:
-
a. 把数据传递到登录页面,登录成功后,把数据在传递到目标页。登录页面除了登录功能还有传递数据的功能,但是由于要跳转的页面和登录页是多对一的关系,所以登录页面要用一个标记记录目标页,而且要传递数据的时候也要经过登录页。
-
b.利用startActivityForResult异步回调将登录结果返回给源Activity,源Activity在onActivityResult进行下一步操作。
-
c.使用动态代理的技术实现。
-
d.参考插件化中启动插件activity的方式,使用Hook技术修改系统startActivity的行为
本篇文章主要介绍第一种方案,第一种方案的特点是,简单易上手不容易出错,缺点是你自己要传递的数据被登录页面给窃取了,当要跳转的页面比较多的时候,登录页面就会变得臃肿庞大,登录页面多了一些额为的不属于它的工作。
举例介绍
这里举一个简单的例子:主页两个按钮分别跳转到我的收藏 我的产品两个页面,这两个页面都需要登录。项目的目录结构如下:
登录拦截拦截器.pngConstant 记录一些常量
LoginActivity 登录页
MainActivity 主页
MyFavoriteActivity 我的收藏
MyGoodsActivity 我的产品
不传递数据的时候
主页的布局不在介绍,直接说明主页按钮的事件的处理:
public class MainActivity extends AppCompatActivity {
private Button myGoodsBtn, myFavoritesBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myGoodsBtn = findViewById(R.id.myGoodsBtn);
myFavoritesBtn = findViewById(R.id.myFavoriteBtn);
myGoodsBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
lookMyGoods();
}
});
myFavoritesBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
lookMyFavorite();
}
});
}
private void lookMyGoods() {
if (Constant.isLogin) {
MyGoodsActivity.launch(this);
}else {
LoginActivity.launch(this, Constant.REQUEST_CODE_GOODS);
}
}
private void lookMyFavorite() {
if (Constant.isLogin) {
MyFavoriteActivity.launch(this);
}else {
LoginActivity.launch(this, Constant.REQUEST_CODE_FAVORITE);
}
}
逻辑很简单:没登录就跳转到登录页,但是要传递一个标记过去。登录的时候直接跳转到目标页。
我的收藏页面
public class MyFavoriteActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_favorite);
}
public static void launch(Activity activity){
Intent intent = new Intent(activity, MyFavoriteActivity.class);
activity.startActivity(intent);
}
}
我的产品页
public class MyGoodsActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_goods);
}
public static void launch(Activity activity){
Intent intent = new Intent(activity, MyGoodsActivity.class);
activity.startActivity(intent);
}
登录页
public class LoginActivity extends AppCompatActivity {
private EditText userNameEditTv, passwordEditTv;
private int nextForwardCode = -1;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
nextForwardCode = getIntent().getIntExtra(KEY_NEXT_FORWARD, -1);
userNameEditTv = findViewById(R.id.userNameEditTv);
passwordEditTv = findViewById(R.id.passwardEditT);
Button loginButton = findViewById(R.id.loginBtn);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Constant.isLogin) {
Toast.makeText(LoginActivity.this, "亲,您已经登录了,请不要重复登录!", Toast.LENGTH_LONG).show();
} else {
if (TextUtils.isEmpty(userNameEditTv.getText()) || TextUtils.isEmpty(passwordEditTv.getText())) {
Toast.makeText(LoginActivity.this, "亲,请输入合法的用户名或者密码!", Toast.LENGTH_LONG).show();
return;
}
Constant.isLogin = true;
Toast.makeText(LoginActivity.this, "亲,登录成功!", Toast.LENGTH_LONG).show();
handleLoginSuccess();
}
}
});
}
/**
* 不传递数据
*/
private void handleLoginSuccess() {
if (nextForwardCode == -1) {
return;
}
if (nextForwardCode == Constant.REQUEST_CODE_GOODS) {
//todo 查看我的商品
MyGoodsActivity.launch(this);
finish();
} else if (nextForwardCode == Constant.REQUEST_CODE_FAVORITE) {
//todo 查看我的收藏
MyFavoriteActivity.launch(this);
finish();
}
}
private static final String KEY_NEXT_FORWARD = "next_forward";
public static void launch(Activity activity, int code) {
Intent intent = new Intent(activity, LoginActivity.class);
intent.putExtra(KEY_NEXT_FORWARD, code);
activity.startActivity(intent);
}
}
登录页面主要就是根据传递过来的KEY_NEXT_FORWARD来分别跳转到不同的目标页。
这种页面跳转的实现起来较简单,但是当传递数据的时候,就比较棘手了。
传递数据的时候
传递数据的时候要把数据传递给登录页,登录页要进行分发,所以登录页面又多了一分责任。
修改后的我的商品页面:
public class MyGoodsActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_goods);
String data = getIntent().getStringExtra(KEY_DATA);
if (!TextUtils.isEmpty(data)) {
Toast.makeText(this, "我的产品--》data="+data,Toast.LENGTH_LONG).show();
}
Bundle bundle = getIntent().getBundleExtra(Constant.KEY_DATA);
if (bundle != null) {
String msg = bundle.getString(Constant.KEY_MSG);
if (!TextUtils.isEmpty(msg)) {
Toast.makeText(this, "我的产品--》msg="+msg,Toast.LENGTH_LONG).show();
}
}
}
public static void launch(Activity activity){
Intent intent = new Intent(activity, MyGoodsActivity.class);
activity.startActivity(intent);
}
private static final String KEY_DATA = "data";
public static void launchForResult(Activity activity, String data){
Intent intent = new Intent(activity, MyGoodsActivity.class);
intent.putExtra(KEY_DATA, data);
activity.startActivity(intent);
}
public static void launch(Activity activity, Bundle bundle){
Intent intent = new Intent(activity, MyGoodsActivity.class);
intent.putExtra(Constant.KEY_DATA, bundle);
activity.startActivity(intent);
}
}
修改后的收藏页面:
public class MyFavoriteActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_favorite);
String data = getIntent().getStringExtra(KEY_DATA);
if (!TextUtils.isEmpty(data)) {
Toast.makeText(this, "我的收藏--》data="+data,Toast.LENGTH_LONG).show();
}
Bundle bundle = getIntent().getBundleExtra(Constant.KEY_DATA);
if (bundle != null) {
String msg = bundle.getString(Constant.KEY_MSG);
if (!TextUtils.isEmpty(msg)) {
Toast.makeText(this, "我的收藏--》msg="+msg,Toast.LENGTH_LONG).show();
}
}
}
public static void launch(Activity activity){
Intent intent = new Intent(activity, MyFavoriteActivity.class);
activity.startActivity(intent);
}
private static final String KEY_DATA = "data";
public static void launch(Activity activity, String data){
Intent intent = new Intent(activity, MyGoodsActivity.class);
intent.putExtra(KEY_DATA, data);
activity.startActivity(intent);
}
}
修改后的主页:
public class MainActivity extends AppCompatActivity {
......
private void lookMyGoods() {
if (Constant.isLogin) {
// MyGoodsActivity.launch(this);
MyGoodsActivity.launch(this, "产品");
}else {
// LoginActivity.launch(this, Constant.REQUEST_CODE_GOODS);
Bundle bundle = new Bundle();
bundle.putString(Constant.KEY_MSG, "通过登录传递的产品");
LoginActivity.launch(this, Constant.REQUEST_CODE_GOODS,bundle);
}
}
private void lookMyFavorite() {
if (Constant.isLogin) {
// MyFavoriteActivity.launch(this);
MyFavoriteActivity.launch(this, "收藏");
}else {
// LoginActivity.launch(this, Constant.REQUEST_CODE_FAVORITE);
Bundle bundle = new Bundle();
bundle.putString(Constant.KEY_MSG, "通过登录传递的收藏");
LoginActivity.launch(this, Constant.REQUEST_CODE_FAVORITE,bundle);
}
}
}
修改后的登录页:
public class LoginActivity extends AppCompatActivity {
...
private Bundle bundle;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Constant.isLogin) {
Toast.makeText(LoginActivity.this, "亲,您已经登录了,请不要重复登录!", Toast.LENGTH_LONG).show();
} else {
if (TextUtils.isEmpty(userNameEditTv.getText()) || TextUtils.isEmpty(passwordEditTv.getText())) {
Toast.makeText(LoginActivity.this, "亲,请输入合法的用户名或者密码!", Toast.LENGTH_LONG).show();
return;
}
Constant.isLogin = true;
Toast.makeText(LoginActivity.this, "亲,登录成功!", Toast.LENGTH_LONG).show();
// handleLoginSuccess();
handleLoginSuccess2();
}
}
});
}
...
/**
* 传递数据
*/
private void handleLoginSuccess2(){
if (bundle == null) {
return;
}
if (nextForwardCode == Constant.REQUEST_CODE_GOODS) {
//todo 查看我的商品
MyGoodsActivity.launch(this, bundle);
finish();
} else if (nextForwardCode == Constant.REQUEST_CODE_FAVORITE) {
//todo 查看我的收藏
MyGoodsActivity.launch(this, bundle);
finish();
}
}
.......
public static void launch(Activity activity, int code, Bundle bundle) {
Intent intent = new Intent(activity, LoginActivity.class);
intent.putExtra(KEY_NEXT_FORWARD, code);
intent.putExtra(Constant.KEY_DATA, bundle);
activity.startActivity(intent);
}
}
从handleLoginSuccess2方法可以看出,在项目中当很多要跳转的页面的时候,这个方法内部就要写很多switch语句,冗余的代码势必增加日后项目的维护难度,而且登录页面承担了一些额为的责任,这也违背了软件设计原则的单一原则。
但是这种方式也有优点就是容易上手,如果是项目周期短,可以采用这种方案。
下一篇介绍第二种方案
网友评论