Android开发中使用static变量应该注意的问题
package com.highxin.launcher01; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map; import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.PhoneLookup;
import android.provider.MediaStore;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView; public class MainActivity extends Activity implements Runnable,OnItemClickListener{
String name = "";
String phoneNO = "";
public static List<Map<String, Object>> contacts_list = new ArrayList<Map<String, Object>>();
public static List<Map<String, Object>> gv_applist = new ArrayList<Map<String,Object>>();
public static boolean switch_flag = false;
public static boolean click_flag = false;
public static boolean firstload_flag = false;//判断桌面是否是第一次加载
public static List<Integer> click_position = new ArrayList<Integer>();
private Intent serviceIntent; public static List<ResolveInfo> appInfos;
public static List<ResolveInfo> showappInfos;
public static List<Map<String, Object>> lv_applist = new ArrayList<Map<String,Object>>();
public static List<Map<String, Object>> lv_addapplist = new ArrayList<Map<String,Object>>();
public static List<Map<String, Object>> lv_delapplist = new ArrayList<Map<String,Object>>(); static int []clickinfo; static GridView gv_app; String []appname ={"联系人","相机","电话","收音机","手电筒","更多"};
int []appicon = {R.drawable.contact,R.drawable.camera,R.drawable.dial,R.drawable.fm,R.drawable.light_off,R.drawable.shop}; private Handler mHandler = new Handler() { @Override
public void handleMessage(Message msg) {
super.handleMessage(msg); showappInfos = appInfos; for(int i=0; i<appInfos.size();i++) {
if((appInfos.get(i).loadLabel(getPackageManager()).equals("相机") &&
appInfos.get(i).activityInfo.packageName.equals("com.android.camera")) ||
(appInfos.get(i).loadLabel(getPackageManager()).equals("收音机") &&
appInfos.get(i).activityInfo.packageName.equals("com.miui.fmradio")) ||
(appInfos.get(i).loadLabel(getPackageManager()).equals("老人桌面") &&
appInfos.get(i).activityInfo.packageName.equals("com.highxin.launcher01")) ){
showappInfos.remove(i);
}
}
clickinfo = new int[showappInfos.size()];
gv_app.setAdapter(new GridViewAdapter(MainActivity.this,gv_applist));
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
Drawable drawable_appicon = null;
String s_appname = null;
serviceIntent = new Intent(this, LightService.class);
// if(!firstload_flag) {
for(int i=0; i<appname.length;i++) {
drawable_appicon = getResources().getDrawable(appicon[i]);
s_appname = appname[i];
Map<String, Object> map = new HashMap<String, Object>();
map.put("appname", s_appname);
map.put("drawable", drawable_appicon); gv_applist.add(map);
}
// firstload_flag = true;
// }
gv_app = (GridView) findViewById(R.id.gv_apps); gv_app.setOnItemClickListener(this); Thread t = new Thread(this);
t.start();
} private List<Map<String, Object>> fillMaps() {
List<Map<String, Object>> items = new ArrayList<Map<String, Object>>(); ContentResolver cr = getContentResolver();
HashMap<String,ArrayList<String>> hashMap = new HashMap<String,ArrayList<String>>();
Cursor phone = cr.query(CommonDataKinds.Phone.CONTENT_URI,
new String[] {
CommonDataKinds.Phone.CONTACT_ID,
CommonDataKinds.Phone.DISPLAY_NAME,
CommonDataKinds.Phone.NUMBER,
CommonDataKinds.Phone.DATA1
//CommonDataKinds.StructuredPostal.DATA3,
},
null, null, null);
while (phone.moveToNext()) {
String contactId = phone.getString(phone.getColumnIndex(CommonDataKinds.Phone.CONTACT_ID));
String displayName = phone.getString(phone.getColumnIndex(CommonDataKinds.Phone.DISPLAY_NAME));
String PhoneNumber = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String address = phone.getString(phone.getColumnIndex(CommonDataKinds.Phone.DATA1)); //以contactId为主键,把同一人的所有电话都存到一起。
ArrayList<String> ad = hashMap.get(contactId);
if(ad == null){
ad = new ArrayList<String>();
ad.add(displayName);
ad.add(PhoneNumber);
//ad.add(address); hashMap.put(contactId, ad);
}
else{
ad.add(PhoneNumber);
} }
phone.close(); ArrayList<String> tmpList;
String tmpStr = "";
int k;
Iterator iter = hashMap.entrySet().iterator();
while (iter.hasNext()) {
HashMap.Entry entry = (HashMap.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue(); tmpList = (ArrayList) val;
tmpStr = tmpList.get(1);
//注释掉的为读取多个联系人的方法
// for(k = 1; k < tmpList.size(); k++){
// tmpStr = tmpStr + tmpList.get(k) + ',' ;
// } HashMap<String, Object> tmpMap = new HashMap<String, Object>();
tmpMap.put("name", tmpList.get(0));
tmpMap.put("phoneNO", tmpStr);
tmpMap.put("img", R.drawable.image); items.add(tmpMap);
}
return items;
} class GridViewAdapter extends BaseAdapter{ LayoutInflater inflater;
List<Map<String, Object>> gvlist;
public GridViewAdapter(Context context,List<Map<String, Object>> locallist) {
inflater = LayoutInflater.from(context);
gvlist = locallist;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return gvlist.size();
} @Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return gvlist.get(position);
} @Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub View view = inflater.inflate(R.layout.gv_item, null);
TextView name = (TextView)view.findViewById(R.id.gv_item_appname);
ImageView iv = (ImageView)view.findViewById(R.id.gv_item_icon);
name.setText((CharSequence) gvlist.get(position).get("appname"));
iv.setImageDrawable((Drawable) gvlist.get(position).get("drawable")); return view;
} } @Override
protected void onResume() {
super.onResume();
gv_app.setAdapter(new GridViewAdapter(MainActivity.this,gv_applist));
} @Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
switch(arg2) { case 0:{
contacts_list = fillMaps();
Intent contact = new Intent(MainActivity.this, Contacts.class);
startActivity(contact);
}break;
case 1:{
Intent imageCaptureIntent = new Intent("android.media.action.STILL_IMAGE_CAMERA");
startActivityForResult(imageCaptureIntent,1);
}break;
case 2:{
Intent i = new Intent();
String packageName = "com.android.contacts";
String mainActivityName = "com.android.contacts.activities.TwelveKeyDialer";
i.setComponent(new ComponentName(packageName,mainActivityName));
startActivity(i);
}break;
case 3:{
Intent intent = new Intent();
intent.setPackage("com.miui.fmradio");
startActivityForResult(intent, 3);
}break;
case 4:{
switch_flag = !switch_flag;
if(switch_flag) {
startService(serviceIntent);
ImageView iv = (ImageView) arg1.findViewById(R.id.gv_item_icon);
iv.setImageResource(R.drawable.light); }else {
stopService(serviceIntent);
ImageView iv = (ImageView) arg1.findViewById(R.id.gv_item_icon);
iv.setImageResource(R.drawable.light_off);
}
}break;
case 5:{
Intent applist = new Intent(MainActivity.this, AppList.class);
startActivityForResult(applist,5);
}break;
default:{
Intent i = new Intent();
String packageName = (String) MainActivity.gv_applist.get(arg2).get("pkgname");
String mainActivityName = (String) MainActivity.gv_applist.get(arg2).get("activityname");
i.setComponent(new ComponentName(packageName,mainActivityName));
startActivity(i); }break;
}
} @Override
public void run() { appInfos = getResolveInfoLists();
mHandler.sendEmptyMessage(0);
} /**
* @Title: getResolveInfoLists
* @Description: 它是通过解析< Intent-filter>标签得到有 < action
* android:name=”android.intent.action.MAIN”/> < action
* android:name=”android.intent.category.LAUNCHER”/>
* @param :
* @return List<ResolveInfo>
* @throws
*/
private List<ResolveInfo> getResolveInfoLists() { // TODO Auto-generated method stub
PackageManager packageManager = this.getPackageManager(); Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER); return packageManager.queryIntentActivities(intent, 0);
} @Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
// gv_applist.clear();
} // @Override
// public boolean onKeyDown(int keyCode, KeyEvent event) {
// if (keyCode == KeyEvent.KEYCODE_BACK){
// return true;
// }
// if(keyCode == KeyEvent.KEYCODE_HOME) {
// gv_applist.clear();
// }
//
// return super.onKeyDown(keyCode, event);
//
// }
}
每次按返回键,重新进入程序gv_applist.add(map),会在原来的基础上不断增加。
找到一篇文章是描述的大概也是这个问题:
突然想到了一个问题,因为我在这两个Activity中使用了不一样的结束方式,一个为System.exit(0);一种为finishi();感觉可能是这两个方式造成的,后来经过测试,确实是这两个方式造成的,如果是使用System.exit(0);的方式的话,等于把这个Acitvity结束了,因此他所操作过的数据都不会再存在了,系统也许认为没有存在的必要了吧,使用finishi();的话,虽然也是退出,但是这个并不是释放资源,只是把当前的Activity推向后台,不再显示,但是他不释放资源,具体资源什么时候释放,由系统决定,当然System.exit(0);这种形式,也并不是真正的退出系统,因为我们还可能有别的Activity在运行,但是他确实把资源释放了!这个是为什么,不太明白!
的确重写onDestroy(),调用finish方法还是有这个问题,但是调用System.exit(0)就不存在这个问题啦。如果仅仅就是解决这个问题,当然可以继续坚持使用static变量,要么在destroy方法中对gv_applist清零,要么设置变量判断是不是第一次启动。
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
// System.exit(0);
finish();
// gv_applist.clear();
}

但当把这个程序变成桌面程序时,又有一个问题出现啦
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

MainActivity中还有一个变量:static int []clickinfo;这个变量只在点击应用程序后面的按钮时值才会发生改变,为+号时,点击会将图标添加到主屏幕,添加完成之后立即变成-号

gv_applist决定主屏幕上加载哪些图标,但当添加完一个图标之后,立即按home键,(桌面程序被推入后台,但是不释放资源,重启桌面程序)会发现主屏幕仍然存在这个图标,但是原来应用列表里面的-号却变成了加号。
if (MainActivity.clickinfo[position] == 0) {
ibt_operate.setImageDrawable(getResources().getDrawable(
R.drawable.add));
} else {
ibt_operate.setImageDrawable(getResources().getDrawable(
R.drawable.del));
}
但应用列表里的图标仅仅依据clickinfo变量加载,所以可以断定clickinfo被初始化成全零啦。
static int []clickinfo;
public static List<Map<String, Object>> lv_applist = new ArrayList<Map<String,Object>>();
原来定义时,clickinfo没有使用new方法,这种变量进入后台后值是不能够保存的。
如果使用全局变量:
1、尽量减少对代码的同步计算
例如:
for(int i =0;i<list.size;i++){
|
应替换为:
for(int i = 0, int len= list.size();i<len;i++){
|
2、尽量采用lazy loading的策略,在需要的时候才开始创建
例如:
String str = "aaa"; |
应替换为:
if(i ==1){
|
Android开发中使用static变量应该注意的问题的更多相关文章
- Android开发中常见的设计模式
对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的 ...
- android开发中的5种存储数据方式
数据存储在开发中是使用最频繁的,根据不同的情况选择不同的存储数据方式对于提高开发效率很有帮助.下面笔者在主要介绍Android平台中实现数据存储的5种方式. 1.使用SharedPreferences ...
- Android开发中使用七牛云存储进行图片上传下载
Android开发中的图片存储本来就是比较耗时耗地的事情,而使用第三方的七牛云,便可以很好的解决这些后顾之忧,最近我也是在学习七牛的SDK,将使用过程在这记录下来,方便以后使用. 先说一下七牛云的存储 ...
- 讨论Android开发中的MVC设计思想
最近闲着没事,总是想想做点什么.在时间空余之时给大家说说MVC设计思想在Android开发中的运用吧! MVC设计思想在Android开发中一直都是一套比较好的设计思想.很多APP的设计都是使用这套方 ...
- Android开发中的输入合法性检验
Why ? 合法性检查对于程序的健壮性具有重要作用.在Android开发中,良好的合法性检查设计机制可以使程序更加清晰,产生bug更少,交互更加友好. What ? 合法性检查的目的在于确定边界.对于 ...
- 关于Android开发中的证书和密钥等问题
关于Android开发中的证书和密钥等问题 引言 除了Android发布应用签名时需要用到证书外,在进行google Map Api开发和Facebook SDK API开发等时都需要申请API Ke ...
- Android开发中,那些让您觉得相见恨晚的方法、类或接口
Android开发中,那些让你觉得相见恨晚的方法.类或接口本篇文章内容提取自知乎Android开发中,有哪些让你觉得相见恨晚的方法.类或接口?,其实有一部是JAVA的,但是在android开发中也算常 ...
- android开发中系统自带语音模块的使用
android开发中系统自带语音模块的使用需求:项目中需要添加语音搜索模块,增加用户体验解决过程:在网上搜到语音搜索例子,参考网上代码,加入到了自己的项目,完成产品要求.这个问题很好解决,网上能找到很 ...
- 如何在Android开发中让你的代码更有效率
最近看了Google IO 2012年的一个视频,名字叫做Doing More With Less: Being a Good Android Citizen,主要是讲如何用少少的几句代码来改善And ...
随机推荐
- 2017携程Web前端实习生招聘笔试题总结
考察encodeURI encodeURI(), decodeURI()它们都是Global对象的方法. encodeURI()通过将某些字符的每个实例替换代表字符的UTF-8编码的一个或多个转义字符 ...
- JavaScript 函数的定义-调用、注意事项
函数定义 函数语句定义 function(a,b){ return a+b; } 表达式定义 var add = function(a,b){return a+b}; //函数表达式可以包含名称,这在 ...
- jQuery animate()动画效果
1.jQuery动画效果 jQuery animate()方法用于创建自定义动画 $(selector).animate({params},speed,callback); //必需的 params ...
- 【TED】如何掌握你的自由时间
[TED]如何掌握你的自由时间 生活 某天翻阅自己原来记录的有道云笔记,发现自己在学校的时候,要求自己每周看三个TED视频,并写一些看后的总结,随意翻阅了下,就发现当时做的好的一些笔记,现在一看就能想 ...
- Vue.js动画在项目使用的两个示例
欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 李萌,16年毕业,Web前端开发从业者,目前就职于腾讯,喜欢node.js.vue.js等技术,热爱新技术,热 ...
- iOS 关于定位你该注意的那些事
其实现在对于一个APP来说,定位用户的位置是件很容易的事情,有三种解决方案供您选择: (1)原生 (2)高德地图 (3)百度地图 1.解决方案的选择 其实单说iOS开发来说应用哪种方案都无所谓 ...
- C++queue容器学习(详解)
一.queue模版类的定义在<queue>头文件中. queue与stack模版非常类似,queue模版也需要定义两个模版参数,一个是元素类型,一个是容器类型,元素类型是必要的,容器类型是 ...
- 用Visual Studio2017写静态库
造轮子是一件有趣的事情,VS是一个强大的工具,能胜任超大规模的工程,但是讲真,对不那么大的项目配置起来不是那么友好(网上的其他教程也一点都不友好Orz).这里就展示一下构建一个简单的静态库的正确姿势. ...
- Java中的集合与线程的Demo
一.简单线程同步问题 package com.ietree.multithread.sync; import java.util.Vector; public class Tickets { publ ...
- Laravel 5.2 教程 - 邮件
一.简介 Laravel 的邮件功能基于热门的 SwiftMailer 函数库之上,提供了一个简洁的 API.Laravel为SMTP.Mailgun.Mandrill.Amazon SES.PHP的 ...