Android关于Activity的一些使用和全局管理技巧

来源:互联网 发布:制作毕业证软件 编辑:程序博客网 时间:2024/05/16 14:23

今天以一个小的Demo,来总结一点在Android关于Activity的使用和全局管理的技巧。


效果图:



从这个效果图,我们最直观的能看到的两个比较简单但也具有代表性的功能:

  • 在某个Activity处于非可见状态时(或在非属于于该Activity类的代码中),对其进行一定的界面更新工作。
  • 在任一界面退出程序(管理自己的App里的所有Activity)。


首先我们来看类似于“退出应用”的这个功能,应当怎么样实现。

对于一个Activity来说,我们知道如果调用其finish方法,既代表结束其生命周期。

而同时,一个应用当中的Activity则正是被一个一个压入了返回栈中,

当这条返回栈中所有的activity都结束了自己的生命周期,也就是我们所谓的“退出程序”。

所以,如果很自然的可以想到,如果我们想在自己应用的某个界面中,放置一个“退出应用”的按钮,自然就应当将所有仍处于返回栈当中的activity依次结束其生命周期。


有了思路,我们就可以开始写代码了。


1、首先,我们需要一个全局的用以存放和管理Activity的地方,换言之,也就是我们需要一个集合。

当一个activity被创建和加载时,我们便将其存放进集合当中;而当其执行"onDestroy"走到生命尽头时,则将其从集合中移除。

简单的来说,也就是该集合永远只会存放所有那些仍然处于“存活”状态的活动,而当我们点击“退出应用时”,所做的工作就是将这些仍然存活的活动取出,结束其生命周期。


于是我们首先新建一个activity的工具类:

public class AppActivities {public static HashMap<String, Activity> activities = new HashMap<String, Activity>();public static void addActivityToCache(String activityName, Activity activity) {activities.put(activityName, activity);}public static void destroyActivity(String activityName) {activities.remove(activityName);}public static void finishAll() {Set<String> keys = activities.keySet();for (String key : keys) {Activity ac = activities.get(key);if (!ac.isFinishing()) {ac.finish();}}}}

2、接着,因为我们前面已经说到了,为了管理活动,我们所需要做的是:

在活动被创建时,将活动存放进集合。实际既是在activity的onCreat方法中将其存放进全局的activities。

而活动被销毁时,将其从集合中移除。实际既是在activity的onDestroy方法中将其从activities中移除。


于是,这里我们又可以使用到另外一个“偷懒”的小技巧。

既然我们要在所有的活动中都做这两个工作,总犯不着在所有的Activity类里都敲一遍代码吧。

将重复的工作代码进行抽离,这是我们应该做的。

于是我们可以自定义一个我们自己的Activity基类,去完成统一的工作,然后再让Activity继承我们自己的基类。

public class BaseActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);AppActivities.addActivityToCache(this.getClass().getName(), this);}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();AppActivities.destroyActivity(this.getClass().getName());}}
在此,我们通过反射将activity的类名作为“key”存放进Map当中,

我们的用意是将此作为一个“唯一标识”,这是为了在后面实现我们之前谈到的另一个功能“在活动处于不可见状态”时对其进行更新工作”而准备的。


3、这里顺带的,我们再看android开发的另一个小技巧。

android中context的使用频率应该是最高的,而在有些地方其实并不那么容易获取到context。所以我们往往需要一个全局的Context。

并且根据你应用的实际需求,还有另外一些需要在全局使用到的信息,所以其实我们可以建立一个自己的“Application”类。

在这个Demo里,他可能类似于这样:

public class MyApplication extends Application {private static Context appContext;@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();appContext = getApplicationContext();}public static Context getAppContext() {return appContext;}public static void quitApp(){AppActivities.finishAll();}}

因为,在android里,一个应用初次启动时,系统会自动的去加载Application类去完成一些初始化工作。

所以我们在我们自己的Application-onCreate时,获取一个全局的context保存下来,然后提供get方法供整个程序在其余地方需要时进行获取。

另外我们定义了另一个方法,既“退出应用”的方法,其实际工作很简单,调用Acitivity工具类的finishAll方法,结束所有尚存活的活动的生命周期,进行退出程序。


4、现在,我们来想一下应当怎么样在一个在某个Activity处于非可见状态时(或在非属于于该Activity类的代码中),对其进行一定的界面更新工作。

这样的情况实际还是比较常见,比如:你在service中通过网络从服务器获取到了最新的数据,需要对activity进行更新等等。


这个时候,我们能想到的可能是通过广播或者Messager的方式,但实际上通过回调我们能够效率更高的去实现它。

所以我们定义一个回调的接口:

public interface OnActivityRefreshListener {void refreshView() ;}

5、这个时候,实际上我们的准备工作已经做完了,接下来,我们就来看一下我们怎么样来进行实际应用。

public class MainActivity extends BaseActivity implements OnActivityRefreshListener {private TextView textView;private Button turn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView = (TextView) this.findViewById(R.id.text);turn = (Button) this.findViewById(R.id.turn);turn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, SecondActivity.class);startActivity(intent);}});}@Overridepublic void refreshView() {textView.setText("界面已经被刷新咯!!!");}}

我们让MainActivity继承了BaseActivity,并且实现了OnActivityRefreshListener接口。

所以此时,MainActivity的生命周期管理已经被自动的交给了我们之前创建的AppActivities类,我们不必再操心了。

实现了刷新界面的回调接口,并且根据需求自定义了回调方法“refreshView”。


6、接下来,就该创建第二个界面,来对我们前面所做的工作加以验证了。

public class SecondActivity extends BaseActivity {private Button refreshMainView, quitApp;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);this.setContentView(R.layout.activity_second);refreshMainView = (Button) findViewById(R.id.refresh_main);quitApp = (Button) findViewById(R.id.quit_app);refreshMainView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {MainActivity activity = (MainActivity) AppActivities.activities.get(new MainActivity().getClass().getName());activity.refreshView();}});quitApp.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {MyApplication.quitApp();}});}}

我们在SecondActivity中设置了两个按钮:

一个用于刷新主界面的TextView显示的数据;一个用于“退出应用”。

可以看到,因为我们之前的“辛勤劳动”,此时,我们要做的工作已经变得非常简单:

要刷新主界面的TextView,我们只需要通过反射获取到你想要其进行更新的Activity类的“类名”,获取到其存放在全局集合中的实例,然后执行回调方法,就搞定了。

想想这是多么方便,即便你的应用中有多少Activity,你只需要根据类名,得到想要的activity实例,执行回调则ok了。


而对于退出应用则更简单了,执行MyApplication里的quitApp方法则ok了。


由此,我们通过一个很小的例子,总结了一些关于android开发提交效率和代码复用率的小技巧的原理,

希望自己日积月累,更重要的是深刻的理解这些原理,从而根据实际的需求创造和使用合适的技巧。


3 0
原创粉丝点击