当前位置: 编程技术>移动开发
本页文章导读:
▪wp7最新开发环境mongo上载地址 wp7最新开发环境mongo下载地址
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=77586864-ab15-40e1-bc38-713a95a56a05&displaylang=en
......
▪ 关于保险退出已创建多个Activity的应用 关于安全退出已创建多个Activity的应用
最初看到这个问题,是在一道面试题上。不同与其他面试题,我觉得这道题很具有实际意义。所以先实际操作下,解决这个问题。在此,我也啰嗦一.........
▪ ActivityGroup中展示不同Activity的例子 ActivityGroup中显示不同Activity的例子
public class BeginActivity extends ActivityGroup { private LinearLayout mcontainnerLayout; private Gallery mGalleryMain; private LocalActivityManager mActivityManager; private ImageButton mButton1; pr.........
[1]wp7最新开发环境mongo上载地址
来源: 互联网 发布时间: 2014-02-18
wp7最新开发环境mongo下载地址
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=77586864-ab15-40e1-bc38-713a95a56a05&displaylang=en
[2] 关于保险退出已创建多个Activity的应用
来源: 互联网 发布时间: 2014-02-18
关于安全退出已创建多个Activity的应用
最初看到这个问题,是在一道面试题上。
不同与其他面试题,我觉得这道题很具有实际意义。所以先实际操作下,解决这个问题。
在此,我也啰嗦一下,大概说说解决这个问题的几种方案:
1,借助系统的API
首先,2.2以前和2.2以后采用的方法是不同的。但都是针对系统级别的东西进行操作。从进程和包的角度来达到此效果。
所以需要添加授权,但是遗憾的是,这些方法涉及底层,而且在我们的应用中是起不到效果的。
这个方案被我排除了。
2,抛出异常,Force Close
这个我觉得很不靠谱。这确实能一下子退出应用。
但是,其一:不能保证所有的Activity都被finish;其二:Force Close的窗口,这个是很糟糕的,当然可以重写一些方法,使不弹出这个窗口。
这个方案也被我排除了。
3,递归退出
使用startActivityForResult打开新的Activity,并加上标识。
在onActivityResult中进行处理,递归关闭。
这个方式我不是很清楚其具体做法,感觉有些复杂。
4,发送特定广播
这个办法是我最赞同的,但是实际操作起来确遇到了问题。
首先看onReceive(Context context, Intent intent)方法,
可以通过context取得ActivityManager,之后取得当前运行的task的信息,看起来离成功不远了。
Activity是被组织在task中的,获得了task信息,那是不是就可以取得其中的Activity实例?
先看看代码:
包含task信息的是一个ActivityManager的静态内部类,RunningTaskInfo。
不过从中能取得的信息有限:
这就有两个问题,
其一,无法取得task中的每一个Activity
其二,不能取得Activity的实例
我的研究到此止步,希望有达人能为我解惑。
5,记录每一个创建的Activity,这也是我最后采用的方法。
为入口Activity添加一个静态的List<Activity>,
之后,每一个Activiity的onCreate方法中,将自身加入这个List,
当程序退出时,遍历这个List,执行finish方法
测试了一下,能达到效果。
但是还是有一点担心,这就是Activity成员变量的生命周期问题,
当该成员变量的生命周期大于Activity的生命周期,就有可能造成内存泄露。
不知这样的有没有这个问题。请高手指教。
在我机器上copy出来的代码, setState(we)忘记删除了
就事论事的说, 在这个问题上 Static 和 application 没什么区别,只不过sdk既然提供了Application ,那就用上了而已。
代码没调试,给你造成了不便,多包涵
这个相当于保存用户的配置吧,我是这么理解的
可以在退出时,记录最后显示的Activity的标识,并写入配置,比如SharedPreference之类的
在入口Activity的onCreate方法中读取这个配置,根据记录,进行跳转
这是我想到的方法,不知对不对
这个相当于保存用户的配置吧,我是这么理解的
可以在退出时,记录最后显示的Activity的标识,并写入配置,比如SharedPreference之类的
在入口Activity的onCreate方法中读取这个配置,根据记录,进行跳转
这是我想到的方法,不知对不对
可以在退出时,用一个标志位来记录你最后退出时的那个Activity,并将标志位信息保存到SharedPreference之中,或者一个文件中,然后在首页的Activity的onCreate方法中读取这个标志信息位,if(flag=="指定标志位")
{
//跳转到退出时的那个Activiy页面
setcontentView(R.layout.id1)
}
else {
//跳转到默认主页
setcontentView(R.layout.defaultId)
}
最初看到这个问题,是在一道面试题上。
不同与其他面试题,我觉得这道题很具有实际意义。所以先实际操作下,解决这个问题。
在此,我也啰嗦一下,大概说说解决这个问题的几种方案:
1,借助系统的API
首先,2.2以前和2.2以后采用的方法是不同的。但都是针对系统级别的东西进行操作。从进程和包的角度来达到此效果。
所以需要添加授权,但是遗憾的是,这些方法涉及底层,而且在我们的应用中是起不到效果的。
这个方案被我排除了。
2,抛出异常,Force Close
这个我觉得很不靠谱。这确实能一下子退出应用。
但是,其一:不能保证所有的Activity都被finish;其二:Force Close的窗口,这个是很糟糕的,当然可以重写一些方法,使不弹出这个窗口。
这个方案也被我排除了。
3,递归退出
使用startActivityForResult打开新的Activity,并加上标识。
在onActivityResult中进行处理,递归关闭。
这个方式我不是很清楚其具体做法,感觉有些复杂。
4,发送特定广播
这个办法是我最赞同的,但是实际操作起来确遇到了问题。
首先看onReceive(Context context, Intent intent)方法,
可以通过context取得ActivityManager,之后取得当前运行的task的信息,看起来离成功不远了。
Activity是被组织在task中的,获得了task信息,那是不是就可以取得其中的Activity实例?
先看看代码:
//通过context获取系统服务,得到ActivityManager ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); //获取当前运行中的TaskInfo //获取的是一个List集合,也就是说当前系统中的task有多个,在我测试代码中有2个 //关于该方法的参数,我从源码看了下,是指返回集合的最大可能条目数,实际返回数可能 //小于这个数目,取决于用户启动了几个task List<ActivityManager.RunningTaskInfo> tasks = manager.getRunningTasks(10);
包含task信息的是一个ActivityManager的静态内部类,RunningTaskInfo。
不过从中能取得的信息有限:
//task栈底的Activity ComponentName baseActivity = task.baseActivity; //task栈顶的Activity ComponentName topActivity = task.topActivity;
这就有两个问题,
其一,无法取得task中的每一个Activity
其二,不能取得Activity的实例
我的研究到此止步,希望有达人能为我解惑。
5,记录每一个创建的Activity,这也是我最后采用的方法。
为入口Activity添加一个静态的List<Activity>,
之后,每一个Activiity的onCreate方法中,将自身加入这个List,
当程序退出时,遍历这个List,执行finish方法
for (Activity act : MainActivity.tasks) { if(!act.isFinishing()){ act.finish(); } } MainActivity.tasks = null;
测试了一下,能达到效果。
但是还是有一点担心,这就是Activity成员变量的生命周期问题,
当该成员变量的生命周期大于Activity的生命周期,就有可能造成内存泄露。
不知这样的有没有这个问题。请高手指教。
1 楼
mikewang
2011-05-23
public class MyApp extends Application {
private List<Activity> mainActivity = new ArrayList<Activity>();
public List<Activity> MainActivity () {
return mainActivity ;
}
public void addActivity(Activity act) {
mainActivity.add(act);
}
public void finishAll()
{
for (Activity act : mainActivity.tasks) {
if(!act.isFinishing()){
act.finish();
}
}
MainActivity.tasks = null;
}
@Override
public void onCreate() {
super.onCreate();
setState(we);
MyApp appState = (MyApp)getApplicationContext();
appState.addActivity(this)
}
结束代码
MyApp appState = (MyApp)getApplicationContext();
appState .finishAll()
代码随手写的,没调试,参考而已
别忘了在manifest中的application标签中添加 android:name=".MyApp"
private List<Activity> mainActivity = new ArrayList<Activity>();
public List<Activity> MainActivity () {
return mainActivity ;
}
public void addActivity(Activity act) {
mainActivity.add(act);
}
public void finishAll()
{
for (Activity act : mainActivity.tasks) {
if(!act.isFinishing()){
act.finish();
}
}
MainActivity.tasks = null;
}
@Override
public void onCreate() {
super.onCreate();
setState(we);
MyApp appState = (MyApp)getApplicationContext();
appState.addActivity(this)
}
结束代码
MyApp appState = (MyApp)getApplicationContext();
appState .finishAll()
代码随手写的,没调试,参考而已
别忘了在manifest中的application标签中添加 android:name=".MyApp"
2 楼
Lagunarock
2011-05-24
谢谢楼上兄台回复
我仔细看了下,兄台的整体思路和我一样
不同之处在于,是利用了自定义Application来管理存储Activity的集合
这样做是为了避免生命周期的问题吗?
setState(we);
这一句代码没看懂,请问下是什么意思?
我仔细看了下,兄台的整体思路和我一样
不同之处在于,是利用了自定义Application来管理存储Activity的集合
这样做是为了避免生命周期的问题吗?
setState(we);
这一句代码没看懂,请问下是什么意思?
3 楼
gyht0808
2011-05-24
用全局保存变量的方式就可以了 就像2楼所说的方法,生命周期是整个程序的运行时间
4 楼
Lagunarock
2011-05-24
也就是说
可以在入口Activity里用一个public static List来保存么?
可以在入口Activity里用一个public static List来保存么?
5 楼
mikewang
2011-05-24
Lagunarock 写道
谢谢楼上兄台回复
我仔细看了下,兄台的整体思路和我一样
不同之处在于,是利用了自定义Application来管理存储Activity的集合
这样做是为了避免生命周期的问题吗?
setState(we);
这一句代码没看懂,请问下是什么意思?
我仔细看了下,兄台的整体思路和我一样
不同之处在于,是利用了自定义Application来管理存储Activity的集合
这样做是为了避免生命周期的问题吗?
setState(we);
这一句代码没看懂,请问下是什么意思?
在我机器上copy出来的代码, setState(we)忘记删除了
就事论事的说, 在这个问题上 Static 和 application 没什么区别,只不过sdk既然提供了Application ,那就用上了而已。
代码没调试,给你造成了不便,多包涵
6 楼
Lagunarock
2011-05-24
兄台客气了
Application是系统提供的一种数据共享方式
确实应当用上,你的代码给了我很大的帮助,谢谢
Application是系统提供的一种数据共享方式
确实应当用上,你的代码给了我很大的帮助,谢谢
7 楼
greatwqs
2011-05-26
添加一个菜单 : 我采用这样的方式关闭:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 1, 1, "注销");
menu.add(0, 2, 2, "退出");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == 1) {
// 菜单1事件
Intent intent = new Intent();
intent.setClass(HiMainActivity.this, HiLoginActivity.class);
HiMainActivity.this.startActivity(intent);
finish();
} else if (item.getItemId() == 2) {
// 菜单2事件
new AlertDialog.Builder(HiMainActivity.this)
.setTitle("确定要退出综合收单系统吗?")
.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
android.os.Process
.killProcess(android.os.Process
.myPid());
}
})
.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
}
}).show();
}
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 1, 1, "注销");
menu.add(0, 2, 2, "退出");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == 1) {
// 菜单1事件
Intent intent = new Intent();
intent.setClass(HiMainActivity.this, HiLoginActivity.class);
HiMainActivity.this.startActivity(intent);
finish();
} else if (item.getItemId() == 2) {
// 菜单2事件
new AlertDialog.Builder(HiMainActivity.this)
.setTitle("确定要退出综合收单系统吗?")
.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
android.os.Process
.killProcess(android.os.Process
.myPid());
}
})
.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
}
}).show();
}
return true;
}
8 楼
changkunyang
2011-05-28
恩,最近也遇到这样的问题。另外一个问题就是,比如我当前进入的是B.activity,然后退出,我想要下次程序启动的时候还直接进入这个activity,二不是系统默认的哪个,不知道楼主有没有或建议。
9 楼
Lagunarock
2011-05-28
changkunyang 写道
恩,最近也遇到这样的问题。另外一个问题就是,比如我当前进入的是B.activity,然后退出,我想要下次程序启动的时候还直接进入这个activity,二不是系统默认的哪个,不知道楼主有没有或建议。
这个相当于保存用户的配置吧,我是这么理解的
可以在退出时,记录最后显示的Activity的标识,并写入配置,比如SharedPreference之类的
在入口Activity的onCreate方法中读取这个配置,根据记录,进行跳转
这是我想到的方法,不知对不对
10 楼
nanzhiwen666
2011-05-30
Lagunarock 写道
changkunyang 写道
恩,最近也遇到这样的问题。另外一个问题就是,比如我当前进入的是B.activity,然后退出,我想要下次程序启动的时候还直接进入这个activity,二不是系统默认的哪个,不知道楼主有没有或建议。
这个相当于保存用户的配置吧,我是这么理解的
可以在退出时,记录最后显示的Activity的标识,并写入配置,比如SharedPreference之类的
在入口Activity的onCreate方法中读取这个配置,根据记录,进行跳转
这是我想到的方法,不知对不对
可以在退出时,用一个标志位来记录你最后退出时的那个Activity,并将标志位信息保存到SharedPreference之中,或者一个文件中,然后在首页的Activity的onCreate方法中读取这个标志信息位,if(flag=="指定标志位")
{
//跳转到退出时的那个Activiy页面
setcontentView(R.layout.id1)
}
else {
//跳转到默认主页
setcontentView(R.layout.defaultId)
}
11 楼
admires
2011-05-31
onSaveInstanceState(Bundle outState)
onRestoreInstanceState(Bundle savedInstanceState)
onRestoreInstanceState(Bundle savedInstanceState)
changkunyang 写道
恩,最近也遇到这样的问题。另外一个问题就是,比如我当前进入的是B.activity,然后退出,我想要下次程序启动的时候还直接进入这个activity,二不是系统默认的哪个,不知道楼主有没有或建议。
[3] ActivityGroup中展示不同Activity的例子
来源: 互联网 发布时间: 2014-02-18
ActivityGroup中显示不同Activity的例子
public class BeginActivity extends ActivityGroup {
private LinearLayout mcontainnerLayout;
private Gallery mGalleryMain;
private LocalActivityManager mActivityManager;
private ImageButton mButton1;
private ImageButton mButton2;
private ImageButton mButton3;
private GalleryMainAdapter mGalleryMainAdpter;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
initView();
mActivityManager = this.getLocalActivityManager();
}
private void initView(){
mcontainnerLayout = (LinearLayout)findViewById(R.id.containnerLayout);
mGalleryMain = (Gallery)findViewById(R.id.gallery_main);
mButton1 = (ImageButton)findViewById(R.id.imageButton1);
mButton2 = (ImageButton)findViewById(R.id.imageButton2);
mButton3 = (ImageButton)findViewById(R.id.imageButton3);
mButton1.setOnClickListener(mOnClickListener);
mButton2.setOnClickListener(mOnClickListener);
mButton3.setOnClickListener(mOnClickListener);
mGalleryMainAdpter = new GalleryMainAdapter(BeginActivity.this);
mGalleryMain.setAdapter(mGalleryMainAdpter);
mGalleryMain.setSelection(1);
}
private OnClickListener mOnClickListener = new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.imageButton1:
Intent intent1 = new Intent(BeginActivity.this,ImageViewActivity.class);
View mView1 = mActivityManager.startActivity(null, intent1).getDecorView();
BeginActivity.this.mcontainnerLayout.removeAllViews();
BeginActivity.this.mcontainnerLayout.addView(mView1);
break;
case R.id.imageButton2:
Intent intent2 = new Intent(BeginActivity.this,ImageListActivity.class);
View mView2 = mActivityManager.startActivity(null, intent2).getDecorView();
BeginActivity.this.mcontainnerLayout.removeAllViews();
BeginActivity.this.mcontainnerLayout.addView(mView2);
break;
case R.id.imageButton3:
Intent intent3 = new Intent(BeginActivity.this,ImageListActivity.class);
startActivity(intent3);
break;
default:
break;
}
}
};
}//class
public class BeginActivity extends ActivityGroup {
private LinearLayout mcontainnerLayout;
private Gallery mGalleryMain;
private LocalActivityManager mActivityManager;
private ImageButton mButton1;
private ImageButton mButton2;
private ImageButton mButton3;
private GalleryMainAdapter mGalleryMainAdpter;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
initView();
mActivityManager = this.getLocalActivityManager();
}
private void initView(){
mcontainnerLayout = (LinearLayout)findViewById(R.id.containnerLayout);
mGalleryMain = (Gallery)findViewById(R.id.gallery_main);
mButton1 = (ImageButton)findViewById(R.id.imageButton1);
mButton2 = (ImageButton)findViewById(R.id.imageButton2);
mButton3 = (ImageButton)findViewById(R.id.imageButton3);
mButton1.setOnClickListener(mOnClickListener);
mButton2.setOnClickListener(mOnClickListener);
mButton3.setOnClickListener(mOnClickListener);
mGalleryMainAdpter = new GalleryMainAdapter(BeginActivity.this);
mGalleryMain.setAdapter(mGalleryMainAdpter);
mGalleryMain.setSelection(1);
}
private OnClickListener mOnClickListener = new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.imageButton1:
Intent intent1 = new Intent(BeginActivity.this,ImageViewActivity.class);
View mView1 = mActivityManager.startActivity(null, intent1).getDecorView();
BeginActivity.this.mcontainnerLayout.removeAllViews();
BeginActivity.this.mcontainnerLayout.addView(mView1);
break;
case R.id.imageButton2:
Intent intent2 = new Intent(BeginActivity.this,ImageListActivity.class);
View mView2 = mActivityManager.startActivity(null, intent2).getDecorView();
BeginActivity.this.mcontainnerLayout.removeAllViews();
BeginActivity.this.mcontainnerLayout.addView(mView2);
break;
case R.id.imageButton3:
Intent intent3 = new Intent(BeginActivity.this,ImageListActivity.class);
startActivity(intent3);
break;
default:
break;
}
}
};
}//class
最新技术文章: