• Android项目实战_手机安全卫士系统加速


    ## 1.本地数据库自动更新的工作机制
    1. 开启一个服务,定时访问服务器
    2. 进行版本对比,如果最新版本比较高,获取需要更新的内容
    3. 将新内容插入到本地数据库中

    ## 2.如何处理横竖屏切换
    1. 指定屏幕朝向
    在清单文件对应的Activity中配置android:screenOrientation=”landscape”(横屏,portrait是竖屏);
    2. 设置屏幕旋转时不重新创建Activity
    在清单文件对应的Activity中配置android:configChanges="keyboardHidden|orientation|screenSize",最好这三个都配置,否则不能适配所有机型或sdk版本。
    横竖屏切换时会走Activity的onConfigurationChanged()方法

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
    // 当新设置中,屏幕布局模式为横排时
    if(newConfig.orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
    //TODO 某些操作
    }else{
    //TODO 某些操作
    }
    super.onConfigurationChanged(newConfig);
    }

    ##3.系统控件的样式在哪里定义
    1. 找到文件:sdk/platforms/某个版本/data/res/values/styles.xml
    2. 搜索关注的控件,如ProgressBar

    <style name="Widget.ProgressBar.Horizontal">
    //indeterminate不确定
    <item name="android:indeterminateOnly">false</item>
    //进度条使用的图片
    <item name="android:progressDrawable">@android:drawable/progress_horizontal</item>
    //进度不确定的时候使用的图片,如安装APK时系统的进度条
    <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
    <item name="android:minHeight">20dip</item>
    <item name="android:maxHeight">20dip</item>
    </style>

    ##4.Fragment添加到Activity上有哪些步骤?
    //获得管理器
    FragmentManager fm = getSupportFragmentManager();

    //获得切换Fragment的帮助类,有add添加、delete删除、replace替换、hide隐藏、show显示
    FragmentTransaction ft = fm.beginTransaction();

    //创建Fragment
    CleanCacheFragment f1 = new CleanCacheFragment();
    ft.replace(R.id.fl_container, f1);

    //提交切换Fragment的事务
    ft.commit();

    ##5.Fragment的生命周期
    1. onAttach():Fragment对象跟Activity关联时

    2. onCreate():Fragment对象的初始创建时

    3. onCreateView():创建Fragment的View对象时

    4. onActivityCreate():所依附的Activity对象已经完成了Activity.onCreate()方法时

    5. onStart():界面即将显示给用户,当Activity的onStart方法调用时

    6. onResume():可以获取焦点与用户交互,当Activity的onResume调用时

    7. onPause():Activity被遮挡不可获取焦点调用了onPause时,或者Activity(或其他容器)打开另一个Fragment,当前Fragemnt无法获取焦点时

    8. onStop():Activity不可见调用了onStop()时,或者Activity(或其他容器)打开另一个Fragment当前Fragment不再显示给用户时

    9. onDestroyView():Fragment中的View对象即将被从当前界面中移除时

    10. onDestroy():Fragment对象被销毁时

    11. onDetach():在Fragment对象不再跟它依附的Activity关联的时候,方法会立即被调用

    ## 6.缓存
    路径:data/data/包名/cache。用于存放临时文件,当系统空间不足时会清空该目录数据

    //获取当前应用的缓存文件夹
    context.getCacheDir();

    ## 7.如何从应用源码中定位实现逻辑
    1. 通过UI上一些字符串进行全局搜索,Ctrl+H 中的 FileSearch
    2. 通过string.xml中对应字符串id定位layout布局
    3. 通过layout布局中的id,定位代码中该View的事件逻辑

    ## 8.如何获取应用的缓存
    1. 经过分析源码,发现获取应用的缓存可以使用packageManager.getPackageSizeInfo()方法
    2. pm的getPackageSizeInfo()方法为hide,无法直接调用,所以使用反射调用该方法
    3. getPackageSizeInfo()需要两个参数,第一个为包名,第二个为一个回调接口IPackageStatsObserver.Stub这种形式一般为远程调用系统服务,需要使用aidl,将aidl文件拷贝到本项目中,注意要使用aidl文件中的原始包名
    4. 代码实现,需要权限<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>

    //1.获得packageManager对象
    PackageManager pm = getPackageManager();

    //2.pm的getPackageSizeInfo()方法为hide,使用反射调用
    Method[] methods = PackageManager.class.getDeclaredMethods();
    for(Method method:methods){
    if("getPackageSizeInfo".equals(method.getName())){
    try {

    //3.第二个参数需要使用aidl创建
    method.invoke(pm, "com.hb.testcache",new IPackageStatsObserver.Stub(){
    @Override
    public void onGetStatsCompleted(PackageStats pStats,
    boolean succeeded) throws RemoteException {
    long cacheSize = pStats.cacheSize;
    System.out.println("缓存大小:"+cacheSize);
    }
    });
    } catch (Exception e) {
    e.printStackTrace();
    }
    return;
    }
    }

    ###界面实现步骤:

    1. 在onstart方法中开启子线程获取每一个应用程序的包名,缓存大小,应用名等信息
    2. 在扫描的过程中睡眠50毫秒去显示进度条的更新
    3. 通过handler消息机制来更新textview文本显示正在扫描的应用程序
    4. 扫描完毕更新ui显示有缓存的应用程序(Linearlayout添加多个textview实现)

    注意:应用程序的包名,缓存大小,应用名等最好做成一个业务bean,方便数据传递和使用


    ## 9.如何清除一个应用的缓存
    需要应用为系统应用

    packageManager.deleteApplicationCacheFiles(String packageName,IPackageDataObserver observer)
    权限:要求系统应用
    <uses-permission android:name="android.permission.DELETE_CACHE_FILES" />
    只能通过打开应用详细信息界面,让用户手动去点击清除缓存

    Intent intent = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS");
    intent.addCategory(Intent.CATEGORY_DEFAULT);
    intent.setData(Uri.parse("package:"+info.packName));
    startActivity(intent);

    ###10.清除全部应用缓存
    利用系统漏洞,google忘记把CLEAR\_APP\_CACHE权限声明为只有系统应用才可以申请的权限

    //建议Long.MAX_VALUE。
    PackageManager.freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer);
    //权限
    <uses-permission android:name="android.permission.CLEAR_APP_CACHE" />

    //模拟一个超级大存储空间的请求。
    //freeStorageAndNotify
    Method[] methods = PackageManager.class.getDeclaredMethods();
    for(Method method:methods){
    if("freeStorageAndNotify".equals(method.getName())){
    try {
    method.invoke(pm, Long.MAX_VALUE,new IPackageDataObserver.Stub() {
    @Override
    public void onRemoveCompleted(String packageName, boolean succeeded)
    throws RemoteException {

    }
    });
    } catch (Exception e) {
    e.printStackTrace();
    }
    break;
    }
    }

    activity:

     1 package com.hb.mobilesafe.activities;
     2 
     3 import android.app.Activity;
     4 import android.app.FragmentManager;
     5 import android.app.FragmentTransaction;
     6 import android.os.Bundle;
     7 import android.view.View;
     8 import android.view.View.OnClickListener;
     9 import android.view.Window;
    10 import android.widget.FrameLayout;
    11 import android.widget.LinearLayout;
    12 
    13 import com.hb.demo_mobilesafe.R;
    14 import com.hb.mobilesafe.fragmet.ChacheFramgment;
    15 import com.hb.mobilesafe.fragmet.SdcardFramgment;
    16 
    17 public class SysChacheActivity extends Activity implements OnClickListener {
    18     private FrameLayout fl_content;
    19     private LinearLayout ll_clrea_chache;
    20     private LinearLayout ll_clrean_sdcard;
    21     
    22     @Override
    23     protected void onCreate(Bundle savedInstanceState) {
    24         // TODO Auto-generated method stub
    25         super.onCreate(savedInstanceState);
    26         requestWindowFeature(Window.FEATURE_NO_TITLE);
    27         setContentView(R.layout.activity_syschache);
    28         ll_clrean_sdcard=(LinearLayout) findViewById(R.id.ll_clrean_sdcard);
    29         ll_clrea_chache=(LinearLayout) findViewById(R.id.ll_clrea_chache);
    30         fl_content=(FrameLayout) findViewById(R.id.fl_content);
    31         ll_clrea_chache.setOnClickListener(this);
    32         ll_clrean_sdcard.setOnClickListener(this);
    33         FragmentManager fm = getFragmentManager();
    34         FragmentTransaction ft = fm.beginTransaction();
    35         ft.replace(R.id.fl_content,new ChacheFramgment(SysChacheActivity.this));
    36         ft.commit();
    37     }
    38     @Override
    39     public void onClick(View v) {
    40         FragmentManager fm = getFragmentManager();
    41         FragmentTransaction ft = fm.beginTransaction();
    42         switch (v.getId()) {
    43         case R.id.ll_clrea_chache:
    44             ft.replace(R.id.fl_content,new ChacheFramgment(SysChacheActivity.this));
    45             
    46             break;
    47         case R.id.ll_clrean_sdcard:
    48             
    49             ft.replace(R.id.fl_content, new SdcardFramgment(SysChacheActivity.this));
    50             
    51             break;
    52         }
    53         ft.commit();
    54     }
    55 
    56 }

    fragment:

      1 package com.hb.mobilesafe.fragmet;
      2 
      3 import java.lang.reflect.Method;
      4 import java.util.ArrayList;
      5 import java.util.List;
      6 
      7 import android.annotation.SuppressLint;
      8 import android.app.Fragment;
      9 import android.content.Context;
     10 import android.content.pm.IPackageDataObserver;
     11 import android.content.pm.IPackageStatsObserver;
     12 import android.content.pm.PackageInfo;
     13 import android.content.pm.PackageManager;
     14 import android.content.pm.PackageStats;
     15 import android.graphics.Color;
     16 import android.os.Bundle;
     17 import android.os.Handler;
     18 import android.os.Message;
     19 import android.os.RemoteException;
     20 import android.os.SystemClock;
     21 import android.text.format.Formatter;
     22 import android.view.LayoutInflater;
     23 import android.view.View;
     24 import android.view.View.OnClickListener;
     25 import android.view.ViewGroup;
     26 import android.widget.Button;
     27 import android.widget.LinearLayout;
     28 import android.widget.ProgressBar;
     29 import android.widget.TextView;
     30 
     31 import com.hb.demo_mobilesafe.R;
     32 import com.hb.mobilesafe.bean.AppChacheInfo;
     33 
     34 @SuppressLint("InflateParams") 
     35 public class ChacheFramgment extends Fragment {
     36 
     37 
     38     protected static final int CHACHE = 0;
     39     private static final int SIZE = 1;
     40     private TextView tv_show_name;
     41     private LinearLayout ll_show_content;
     42     private Button bt_clean;
     43     private Context context;
     44     private PackageManager pm;
     45     private ProgressBar pg_gram;
     46     public ChacheFramgment(Context context){
     47         this.context=context;
     48     }
     49     private Handler handler=new Handler(){
     50         public void handleMessage(android.os.Message msg) {
     51             switch (msg.what) {
     52             case 0:
     53                 tv_show_name.setText("扫描完成");
     54                 pg_gram.setVisibility(View.GONE);
     55                 break;
     56 
     57             case SIZE:
     58                 AppChacheInfo appinfo=(AppChacheInfo)msg.obj;
     59                 tv_show_name.setText("正在扫描:"+appinfo.getAppName());
     60                 TextView textView=new TextView(context);
     61                 textView.setTextColor(Color.RED);
     62                 if(appinfo.getAppChaCheSize()>0){
     63                     textView.setText(appinfo.getAppName()+":"+Formatter.formatFileSize(context, appinfo.getAppChaCheSize()));
     64                     ll_show_content.addView(textView, 0);
     65                 }
     66                 break;
     67             case 3:
     68                 tv_show_name.setText("清理完成");
     69                 ll_show_content.removeAllViews();
     70                 break;
     71             }
     72         };
     73     };
     74     @Override
     75     public View onCreateView(LayoutInflater inflater, ViewGroup container,
     76             Bundle savedInstanceState) {
     77         View view = inflater.inflate(R.layout.fagment_chache, null);
     78         tv_show_name = (TextView) view.findViewById(R.id.tv_show_name);
     79         ll_show_content = (LinearLayout) view.findViewById(R.id.ll_show_content);
     80         bt_clean=(Button) view.findViewById(R.id.bt_clean);
     81         pg_gram=(ProgressBar) view.findViewById(R.id.pB_program);
     82         bt_clean.setOnClickListener(new OnclikLeanEvent());
     83         pm = context.getPackageManager();
     84         return view;
     85     }
     86     @Override
     87     public void onStart() {
     88         super.onStart();
     89         new ThreadRun().start();
     90         
     91     }
     92     /**
     93      * 扫描所有APP
     94      * @return
     95      */
     96     public List<AppChacheInfo> scanApp(){
     97         List<PackageInfo> list = pm.getInstalledPackages(0);
     98         List<AppChacheInfo> aInfo=new ArrayList<AppChacheInfo>();
     99         for (PackageInfo mInfo : list) {
    100             AppChacheInfo info = new AppChacheInfo();
    101             String packageName = mInfo.packageName;
    102             String appName = mInfo.applicationInfo.loadLabel(pm).toString();
    103             info.setAppPacagenName(packageName);
    104             info.setAppName(appName);
    105             aInfo.add(info);
    106         }
    107         int i=0;
    108         for (AppChacheInfo cInfo : aInfo) {
    109             findChache(cInfo.getAppPacagenName(), cInfo);
    110             i++;
    111             pg_gram.setProgress(i);
    112             SystemClock.sleep(200);
    113             Message message=new Message();
    114             message.obj=cInfo;
    115             message.what=SIZE;
    116             handler.sendMessage(message);
    117         }
    118         
    119         return aInfo;
    120 
    121     }
    122 
    123     /**
    124      * 得到缓存
    125      * public abstract void getPackageSizeInfo(String packageName, int userHandle,
    126      *      IPackageStatsObserver observer);
    127      *Stub 存根,负责接收本地方法调用,并将它们赋给各自的具体实现对象
    128      */
    129 
    130     public void findChache(String packageName ,final AppChacheInfo chacheInfo){
    131         try {
    132 
    133             Method method = PackageManager.class.getMethod("getPackageSizeInfo",String.class, IPackageStatsObserver.class);
    134             method.invoke(pm, packageName,new IPackageStatsObserver.Stub() {
    135 
    136                 @Override
    137                 public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
    138                         throws RemoteException {
    139                     long size = pStats.cacheSize;
    140                     chacheInfo.setAppChaCheSize(size);
    141                 }
    142             });
    143         } catch (Exception e) {
    144             e.printStackTrace();
    145         }
    146     }
    147     /**
    148      * 
    149      * @author 清理缓存
    150      * class ClearCacheObserver extends IPackageDataObserver.Stub {
    151         public void onRemoveCompleted(final String packageName, final boolean succeeded) {
    152             final Message msg = mHandler.obtainMessage(CLEAR_CACHE);
    153             msg.arg1 = succeeded ? OP_SUCCESSFUL:OP_FAILED;
    154             mHandler.sendMessage(msg);
    155          }
    156      }
    157      */
    158     private void clean()  {
    159         try {
    160             Method method = PackageManager.class.getMethod("freeStorageAndNotify", long.class,IPackageDataObserver.class);
    161             method.invoke(pm,Long.MAX_VALUE,new IPackageDataObserver.Stub() {
    162 
    163                 @Override
    164                 public void onRemoveCompleted(String packageName, boolean succeeded)
    165                         throws RemoteException {
    166                     handler.sendEmptyMessage(3);
    167                 }
    168             });
    169         } catch (Exception e) {
    170             // TODO Auto-generated catch block
    171             e.printStackTrace();
    172         }
    173     }
    174     class OnclikLeanEvent implements OnClickListener {
    175 
    176         @Override
    177         public void onClick(View v) {
    178             clean();
    179         }
    180 
    181     }
    182     @Override
    183     public void onDestroy() {
    184         super.onDestroy();
    185         new ThreadRun().interrupt();
    186         
    187     }
    188     class ThreadRun extends Thread{
    189         @Override
    190         public void run() {
    191             super.run();
    192             List<AppChacheInfo> app = scanApp();
    193             pg_gram.setMax(app.size());
    194             handler.sendEmptyMessage(0);
    195         }
    196     }
    197     
    198 
    199 }
  • 相关阅读:
    thrift学习
    Spring Bean的生命周期
    无聊的编程题
    jpa双向多对多关联映射
    jpa单向多对多关联映射
    jpa双向一对多关联映射
    jpa单向一对多关联映射
    【计导作业】链表——差集与交集
    【计导作业】链表——成绩统计2
    C语言中访问结构体成员时用‘.’和‘->’的区别
  • 原文地址:https://www.cnblogs.com/boket/p/6991858.html
Copyright © 2020-2023  润新知