Android开发中使用static变量应该注意的问题

  1 package com.highxin.launcher01;
  2
  3
  4
  5 import java.util.ArrayList;
  6 import java.util.HashMap;
  7 import java.util.Iterator;
  8 import java.util.List;
  9 import java.util.Map;
 10
 11 import android.app.Activity;
 12 import android.content.ComponentName;
 13 import android.content.ContentResolver;
 14 import android.content.Context;
 15 import android.content.Intent;
 16 import android.content.pm.ApplicationInfo;
 17 import android.content.pm.PackageInfo;
 18 import android.content.pm.PackageManager;
 19 import android.content.pm.ResolveInfo;
 20 import android.database.Cursor;
 21 import android.graphics.drawable.Drawable;
 22 import android.net.Uri;
 23 import android.os.Bundle;
 24 import android.os.Handler;
 25 import android.os.Message;
 26 import android.provider.ContactsContract;
 27 import android.provider.ContactsContract.CommonDataKinds;
 28 import android.provider.ContactsContract.PhoneLookup;
 29 import android.provider.MediaStore;
 30 import android.util.Log;
 31 import android.view.KeyEvent;
 32 import android.view.LayoutInflater;
 33 import android.view.View;
 34 import android.view.ViewGroup;
 35 import android.view.Window;
 36 import android.widget.AdapterView;
 37 import android.widget.AdapterView.OnItemClickListener;
 38 import android.widget.BaseAdapter;
 39 import android.widget.GridView;
 40 import android.widget.ImageView;
 41 import android.widget.TextView;
 42
 43 public class MainActivity extends Activity implements Runnable,OnItemClickListener{
 44     String name = "";
 45     String phoneNO = "";
 46     public static  List<Map<String, Object>>  contacts_list = new ArrayList<Map<String, Object>>();
 47     public static  List<Map<String, Object>>  gv_applist = new ArrayList<Map<String,Object>>();
 48     public static boolean switch_flag = false;
 49     public static boolean click_flag = false;
 50     public static boolean firstload_flag = false;//判断桌面是否是第一次加载
 51     public static List<Integer> click_position = new ArrayList<Integer>();
 52     private Intent serviceIntent;
 53
 54     public static List<ResolveInfo> appInfos;
 55     public static List<ResolveInfo> showappInfos;
 56     public static  List<Map<String, Object>>  lv_applist = new ArrayList<Map<String,Object>>();
 57     public static  List<Map<String, Object>>  lv_addapplist = new ArrayList<Map<String,Object>>();
 58     public static  List<Map<String, Object>>  lv_delapplist = new ArrayList<Map<String,Object>>();
 59
 60     static int []clickinfo;
 61
 62     static GridView gv_app;
 63
 64     String []appname ={"联系人","相机","电话","收音机","手电筒","更多"};
 65     int []appicon = {R.drawable.contact,R.drawable.camera,R.drawable.dial,R.drawable.fm,R.drawable.light_off,R.drawable.shop};
 66
 67     private Handler mHandler = new Handler() {
 68
 69         @Override
 70         public void handleMessage(Message msg) {
 71             super.handleMessage(msg);
 72
 73              showappInfos = appInfos;
 74
 75
 76              for(int i=0; i<appInfos.size();i++) {
 77                  if((appInfos.get(i).loadLabel(getPackageManager()).equals("相机") &&
 78                      appInfos.get(i).activityInfo.packageName.equals("com.android.camera")) ||
 79                     (appInfos.get(i).loadLabel(getPackageManager()).equals("收音机") &&
 80                     appInfos.get(i).activityInfo.packageName.equals("com.miui.fmradio"))  ||
 81                     (appInfos.get(i).loadLabel(getPackageManager()).equals("老人桌面") &&
 82                      appInfos.get(i).activityInfo.packageName.equals("com.highxin.launcher01")) ){
 83                      showappInfos.remove(i);
 84                  }
 85              }
 86              clickinfo = new int[showappInfos.size()];
 87              gv_app.setAdapter(new GridViewAdapter(MainActivity.this,gv_applist));
 88         }
 89     };
 90
 91
 92     @Override
 93     protected void onCreate(Bundle savedInstanceState) {
 94         super.onCreate(savedInstanceState);
 95         requestWindowFeature(Window.FEATURE_NO_TITLE);
 96         setContentView(R.layout.activity_main);
 97         Drawable drawable_appicon = null;
 98         String s_appname = null;
 99         serviceIntent = new Intent(this, LightService.class);
100 //        if(!firstload_flag) {
101             for(int i=0; i<appname.length;i++) {
102                 drawable_appicon = getResources().getDrawable(appicon[i]);
103                 s_appname = appname[i];
104                 Map<String, Object> map = new HashMap<String, Object>();
105                 map.put("appname", s_appname);
106                 map.put("drawable", drawable_appicon);
107
108                 gv_applist.add(map);
109              }
110 //            firstload_flag = true;
111 //        }
112         gv_app = (GridView) findViewById(R.id.gv_apps);
113
114         gv_app.setOnItemClickListener(this);
115
116         Thread t = new Thread(this);
117         t.start();
118     }
119
120
121      private List<Map<String, Object>> fillMaps() {
122          List<Map<String, Object>> items = new ArrayList<Map<String, Object>>();
123
124          ContentResolver cr = getContentResolver();
125          HashMap<String,ArrayList<String>> hashMap = new HashMap<String,ArrayList<String>>();
126          Cursor phone = cr.query(CommonDataKinds.Phone.CONTENT_URI,
127            new String[] {
128            CommonDataKinds.Phone.CONTACT_ID,
129            CommonDataKinds.Phone.DISPLAY_NAME,
130            CommonDataKinds.Phone.NUMBER,
131            CommonDataKinds.Phone.DATA1
132            //CommonDataKinds.StructuredPostal.DATA3,
133            },
134            null, null, null);
135          while (phone.moveToNext()) {
136           String contactId = phone.getString(phone.getColumnIndex(CommonDataKinds.Phone.CONTACT_ID));
137           String displayName = phone.getString(phone.getColumnIndex(CommonDataKinds.Phone.DISPLAY_NAME));
138           String PhoneNumber = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
139           String address = phone.getString(phone.getColumnIndex(CommonDataKinds.Phone.DATA1));
140
141           //以contactId为主键,把同一人的所有电话都存到一起。
142          ArrayList<String> ad = hashMap.get(contactId);
143           if(ad == null){
144            ad = new ArrayList<String>();
145            ad.add(displayName);
146            ad.add(PhoneNumber);
147            //ad.add(address);
148
149            hashMap.put(contactId, ad);
150           }
151           else{
152            ad.add(PhoneNumber);
153           }
154
155          }
156          phone.close();
157
158          ArrayList<String> tmpList;
159          String tmpStr = "";
160          int k;
161          Iterator iter = hashMap.entrySet().iterator();
162          while (iter.hasNext()) {
163           HashMap.Entry entry = (HashMap.Entry) iter.next();
164              Object key = entry.getKey();
165              Object val = entry.getValue();
166
167              tmpList = (ArrayList) val;
168              tmpStr =  tmpList.get(1);
169              //注释掉的为读取多个联系人的方法
170 //             for(k = 1; k < tmpList.size(); k++){
171 //              tmpStr = tmpStr + tmpList.get(k) + ‘,‘ ;
172 //             }
173
174              HashMap<String, Object> tmpMap = new HashMap<String, Object>();
175              tmpMap.put("name", tmpList.get(0));
176              tmpMap.put("phoneNO", tmpStr);
177              tmpMap.put("img", R.drawable.image);
178
179              items.add(tmpMap);
180          }
181          return items;
182      }
183
184
185     class GridViewAdapter extends BaseAdapter{
186
187         LayoutInflater inflater;
188         List<Map<String, Object>> gvlist;
189         public GridViewAdapter(Context context,List<Map<String, Object>> locallist) {
190             inflater = LayoutInflater.from(context);
191             gvlist = locallist;
192         }
193         @Override
194         public int getCount() {
195             // TODO Auto-generated method stub
196             return gvlist.size();
197         }
198
199         @Override
200         public Object getItem(int position) {
201             // TODO Auto-generated method stub
202             return gvlist.get(position);
203         }
204
205         @Override
206         public long getItemId(int position) {
207             // TODO Auto-generated method stub
208             return position;
209         }
210
211         @Override
212         public View getView(int position, View convertView, ViewGroup parent) {
213             // TODO Auto-generated method stub
214
215                 View view = inflater.inflate(R.layout.gv_item, null);
216                 TextView name = (TextView)view.findViewById(R.id.gv_item_appname);
217                 ImageView iv = (ImageView)view.findViewById(R.id.gv_item_icon);
218                 name.setText((CharSequence) gvlist.get(position).get("appname"));
219                 iv.setImageDrawable((Drawable) gvlist.get(position).get("drawable"));
220
221             return view;
222         }
223
224     }
225
226
227     @Override
228     protected void onResume() {
229         super.onResume();
230          gv_app.setAdapter(new GridViewAdapter(MainActivity.this,gv_applist));
231     }
232
233     @Override
234     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
235         // TODO Auto-generated method stub
236         switch(arg2) {
237
238             case 0:{
239                     contacts_list = fillMaps();
240                     Intent contact  = new Intent(MainActivity.this, Contacts.class);
241                     startActivity(contact);
242                     }break;
243             case 1:{
244                Intent imageCaptureIntent = new Intent("android.media.action.STILL_IMAGE_CAMERA");
245                startActivityForResult(imageCaptureIntent,1);
246             }break;
247             case 2:{
248                 Intent i = new Intent();
249                 String packageName = "com.android.contacts";
250                 String mainActivityName = "com.android.contacts.activities.TwelveKeyDialer";
251                 i.setComponent(new ComponentName(packageName,mainActivityName));
252                 startActivity(i);
253             }break;
254             case 3:{
255                 Intent intent = new Intent();
256                 intent.setPackage("com.miui.fmradio");
257                 startActivityForResult(intent, 3);
258                 }break;
259             case 4:{
260                     switch_flag = !switch_flag;
261                     if(switch_flag) {
262                         startService(serviceIntent);
263                          ImageView iv = (ImageView) arg1.findViewById(R.id.gv_item_icon);
264                          iv.setImageResource(R.drawable.light);
265
266                     }else {
267                         stopService(serviceIntent);
268                          ImageView iv = (ImageView) arg1.findViewById(R.id.gv_item_icon);
269                          iv.setImageResource(R.drawable.light_off);
270                     }
271                 }break;
272             case 5:{
273                 Intent applist  = new Intent(MainActivity.this, AppList.class);
274                 startActivityForResult(applist,5);
275                 }break;
276             default:{
277                 Intent i = new Intent();
278                 String packageName = (String) MainActivity.gv_applist.get(arg2).get("pkgname");
279                 String mainActivityName = (String) MainActivity.gv_applist.get(arg2).get("activityname");
280                 i.setComponent(new ComponentName(packageName,mainActivityName));
281                 startActivity(i);
282
283
284             }break;
285         }
286     }
287
288     @Override
289     public void run() {
290
291          appInfos = getResolveInfoLists();
292          mHandler.sendEmptyMessage(0);
293     }
294
295
296     /**
297      * @Title: getResolveInfoLists
298      * @Description: 它是通过解析< Intent-filter>标签得到有   < action
299      *               android:name=”android.intent.action.MAIN”/>   < action
300      *               android:name=”android.intent.category.LAUNCHER”/>
301      * @param :
302      * @return List<ResolveInfo>
303      * @throws
304      */
305     private List<ResolveInfo> getResolveInfoLists() {
306
307         // TODO Auto-generated method stub
308         PackageManager packageManager = this.getPackageManager();
309
310         Intent intent = new Intent(Intent.ACTION_MAIN);
311         intent.addCategory(Intent.CATEGORY_LAUNCHER);
312
313         return packageManager.queryIntentActivities(intent, 0);
314     }
315
316     @Override
317     protected void onDestroy() {
318         // TODO Auto-generated method stub
319         super.onDestroy();
320 //        gv_applist.clear();
321     }
322
323 //    @Override
324 //    public boolean onKeyDown(int keyCode, KeyEvent event) {
325 //        if (keyCode == KeyEvent.KEYCODE_BACK){
326 //            return true;
327 //        }
328 //        if(keyCode == KeyEvent.KEYCODE_HOME) {
329 //            gv_applist.clear();
330 //        }
331 //
332 //    return super.onKeyDown(keyCode, event);
333 //
334 //    }
335 }

每次按返回键,重新进入程序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)
    }
时间: 2024-11-10 04:13:30

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

Android 4.1 APP中的static变量即使在APP退出后仍然不会被擦除

Android 4.1 APP中的static变量即使在APP退出后仍然会保留最后赋值状态. public class MainActivity extends Activity { private TextView tv; private static int i=10; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVie

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

Android开发中的图片存储本来就是比较耗时耗地的事情,而使用第三方的七牛云,便可以很好的解决这些后顾之忧,最近我也是在学习七牛的SDK,将使用过程在这记录下来,方便以后使用. 先说一下七牛云的存储原理,上面这幅图片是官方给出的原理图,表述当然比较清晰了.可以看出,要进行图片上传的话可以分为五大步: 1. 客户端用户登录到APP的账号系统里面: 2. 客户端上传文件之前,需要向业务服务器申请七牛的上传凭证,这个凭证由业务服务器使用七牛提供的服务端SDK生成: 3. 客户端使用七牛提供的客户端S

Android开发中无处不在的设计模式——策略模式

这个系列停更了好久了,差不多可以重新拿起来更一篇了,这篇文章主要介绍策略模式.在这之前,先温习一下前面介绍的4种模式. 设计模式很重要! 设计模式很重要! 设计模式很重要! 重要的事说三遍!!! Android开发中无处不在的设计模式--单例模式 Android开发中无处不在的设计模式--Builder模式 Android开发中无处不在的设计模式--观察者模式 Android开发中无处不在的设计模式--原型模式 接着看下策略模式的定义 策略模式定义了一些列的算法,并将每一个算法封装起来,而且使它

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

数据存储在开发中是使用最频繁的,根据不同的情况选择不同的存储数据方式对于提高开发效率很有帮助.下面笔者在主要介绍Android平台中实现数据存储的5种方式. 1.使用SharedPreferences存储数据 SharedPreferences是Android平台上一个轻量级的存储类,主要是保存一些常用的配置比如窗口状态,一般在Activity中 重载窗口状态onSaveInstance State保存一般使用SharedPreferences完成,它提供了Android平台常规的Long长 整

在Android开发中使用ORMLite--篇一

前言 在android开发中,数据需要本地存储,当需要进行一系列的操作时,当然是使用sqlite.标准做法是继承SQLiteOpenHelper,重写onCreate和onUpdate方法.存在比较大的问题是,sql语句需要自己写,比较复杂繁琐而且重复率高,于是找了一个orm框架在新写的app中进行试用. 准备 下载地址:http://ormlite.com/releases/ 下载core和android两个jar包,并引入工程即可 开发 模型注解 首先定义一个最常见的人员模型 // tabl

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

最近闲着没事,总是想想做点什么.在时间空余之时给大家说说MVC设计思想在Android开发中的运用吧! MVC设计思想在Android开发中一直都是一套比较好的设计思想.很多APP的设计都是使用这套方案完成架构设计的. 谈到MVC我想分为以下几个点分点突进. 1.什么是MVC框架. 2.MVC如何工作 3.MVC的缺点 4.Android之MVC设计模式. 一.什么是MVC框架. MVC英文即Model-View-Controller,即把一个应用的输入.处理.输出流程按照Model.View.

Android开发中在一个Activity中关闭另一个Activity

Android开发中在一个Activity中关闭另一个Activity 比如有ActivityA, ActivityB,在ActivityB中关闭ActivityA 解决方案: 1. 在 ActivityA 里面设置一个静态的变量instance,初始化为this在 ActivityB 里面, ActivityA.instance.finish(); 2. 也可以通过ActivityManager ActivityManager manager = (ActivityManager)getSys

Android开发中常见的设计模式

对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的同学,这里推荐2本书.一本是Head First系列的Head Hirst Design Pattern,英文好的可以看英文,可以多读几遍.另外一本是大话设计模式. 单例模式 首先了解一些单例模式的概念. 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 这样做有以下几个优点 对于

Builder模式详解及其在Android开发中的应用

一.引言 在Android开发中,采用Builder模式的代码随处可见,比如说Android系统对话框AlertDialog的使用或者是Android中的通知栏(Notification)的使用,又比如说在一些常用的第三方库中也随处可见其踪迹,比如说一些常用的网络请求库如OkHttp或者是retrofit,又或者是图片加载库Glide中也不缺乏它的应用. 为什么Builder模式在Android或是Java开发中这么火呢?因为它相较于构造函数或者是Get/Set方法,它的灵活性和封装性上都比较有