zoukankan      html  css  js  c++  java
  • 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      * @param302      * @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)
        }
  • 相关阅读:
    谈一谈对象池SafeObjectPool能干什么
    .net core 程序退出事件
    .NETCore 快速开发做一个简易商城
    Git创建子分支,合并分支并提交
    Vue项目中关闭eslint的方法
    Missing space before function parentheses
    单引号变双引号 格式化去掉分号
    Docker Swarm搭建多服务器下Docker集群
    Asp.Net Core中服务的生命周期选项区别和用法
    KnockoutJS-模板绑定
  • 原文地址:https://www.cnblogs.com/hixin/p/4177668.html
Copyright © 2011-2022 走看看