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){
list.add(str)
}

应替换为:

 if(i ==1){
String str = "aaa"
list.add(str)
}

Android开发中使用static变量应该注意的问题的更多相关文章

  1. Android开发中常见的设计模式

    对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的 ...

  2. android开发中的5种存储数据方式

    数据存储在开发中是使用最频繁的,根据不同的情况选择不同的存储数据方式对于提高开发效率很有帮助.下面笔者在主要介绍Android平台中实现数据存储的5种方式. 1.使用SharedPreferences ...

  3. Android开发中使用七牛云存储进行图片上传下载

    Android开发中的图片存储本来就是比较耗时耗地的事情,而使用第三方的七牛云,便可以很好的解决这些后顾之忧,最近我也是在学习七牛的SDK,将使用过程在这记录下来,方便以后使用. 先说一下七牛云的存储 ...

  4. 讨论Android开发中的MVC设计思想

    最近闲着没事,总是想想做点什么.在时间空余之时给大家说说MVC设计思想在Android开发中的运用吧! MVC设计思想在Android开发中一直都是一套比较好的设计思想.很多APP的设计都是使用这套方 ...

  5. Android开发中的输入合法性检验

    Why ? 合法性检查对于程序的健壮性具有重要作用.在Android开发中,良好的合法性检查设计机制可以使程序更加清晰,产生bug更少,交互更加友好. What ? 合法性检查的目的在于确定边界.对于 ...

  6. 关于Android开发中的证书和密钥等问题

    关于Android开发中的证书和密钥等问题 引言 除了Android发布应用签名时需要用到证书外,在进行google Map Api开发和Facebook SDK API开发等时都需要申请API Ke ...

  7. Android开发中,那些让您觉得相见恨晚的方法、类或接口

    Android开发中,那些让你觉得相见恨晚的方法.类或接口本篇文章内容提取自知乎Android开发中,有哪些让你觉得相见恨晚的方法.类或接口?,其实有一部是JAVA的,但是在android开发中也算常 ...

  8. android开发中系统自带语音模块的使用

    android开发中系统自带语音模块的使用需求:项目中需要添加语音搜索模块,增加用户体验解决过程:在网上搜到语音搜索例子,参考网上代码,加入到了自己的项目,完成产品要求.这个问题很好解决,网上能找到很 ...

  9. 如何在Android开发中让你的代码更有效率

    最近看了Google IO 2012年的一个视频,名字叫做Doing More With Less: Being a Good Android Citizen,主要是讲如何用少少的几句代码来改善And ...

随机推荐

  1. 什么是测试开发工程师-google的解释

    什么是测试开发工程师-google的解释 “ 软件测试开发工程师[SET or Software Engineer in Test],和软件开发工程师一样是开发工程师,主要负责软件的可测试性.他们参与 ...

  2. 老李分享:持续集成学好jenkins

    老李分享:持续集成学好jenkins   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest测试开发工程师就业培训请大 ...

  3. QTP自动化测试培训:描述编程之WebElement

    QTP自动化测试培训:描述编程之WebElement   通过描述性编程技术,来描述出来输入框: set po=browser("creationtime:=0").page(&q ...

  4. Android -- Annotation(注解)原理详解及常见框架应用

    1,我们在上一篇讲到了EventBus源码及3.0版本的简单使用,知道了我们3.0版本是使用注解方式标记事件响应方法的,这里我们就有一个疑问了,为什么在一个方法加上类似于"@Subscrib ...

  5. Jmeter自动化测试工具的简单使用--HTTP测试

    Jmeter自动化测试工具的简单应用 1.安装Jmeter 链接: https://pan.baidu.com/s/1mhSzU68 密码: 446z   到这里下载 1.1 jmeter 将下载好的 ...

  6. 149_best-time-to-buy-and-sell-stock

    /*@Copyright:LintCode@Author:   Monster__li@Problem:  http://www.lintcode.com/problem/best-time-to-b ...

  7. 生肖年(switch练习)

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. Web API 之SelfHost与OwinSelfHots加载外部程序

       下面就一些web api的一些基础内容进行阐述,然后就web api宿主承载中的实际业务问题进行解决 HttpController      HttpController的激活是由处于消息处理管 ...

  9. 在Angular项目下使用Umeditor

    Umeditor是百度旗下的开源富文本编辑器项目,目前用于百度贴吧,是ueditor的迷你版本. 公司的Angular后台管理项目需要上传一些新闻,用Umeditor十分适合.但是目前官方只提供Jsp ...

  10. javascript原生方法实现extend

    var extend = (function () { for(var p in {toString:null}){ //检查当前浏览器是否支持forin循环去遍历出一个不可枚举的属性,比如toStr ...