One-click cleaning of imitation 360 (1) and one-click cleaning of imitation 360
---------------------------------------------------------------------
Compiling environment: Android 4.0
Test environment: Android 4.2.2 Simulator
Screen Resolution: 480*800
Author: Crazy Xiaoqiang
Note:
1. The resources are collected on the Internet. If there is any infringement, please contact in time to handle it.
2. The code is only used for learning and communication. Do not commercialize it.
--------------------------------------------------------------------
First part:
"One-click cleanup" is a desktop icon. After clicking the icon, a view is displayed and an animation is cleared. Then, several processes are cleared and the MB memory is released, click "set Filter list" to start another Activity to edit the Filter list.
AndroidManifest. xml is as follows:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tang.demo360" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/> <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.Black.NoTitleBar" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".CleanActivity" android:theme="@style/MTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> </intent-filter> </activity> <service android:name=".CleanService"> </service> <activity android:name=".SetWhiteListActivity"></activity> </application></manifest>
1. Create a shortcut
The main interface is a button. After you click it, a broadcast com. android. launcher. action. INSTALL_SHORTCUT will be sent to create a shortcut. This requires the permission
<Uses-permission android: name = "com. android. launcher. permission. INSTALL_SHORTCUT"/>
Figure 1 Figure 2
Private void createShortcut () {Intent custom cut = new Intent ("com. android. launcher. action. INSTALL_SHORTCUT "); // The shortcut name String name = getResources (). getString (R. string. app_name); shortcut cut. putExtra (Intent. EXTRA_SHORTCUT_NAME, name); // repeated cut creation is not allowed. putExtra ("duplicate", false); Intent shortcutIntent = new Intent (); ComponentName componentName = new ComponentName (getPackageName (), "com. tang. demo360.CleanActivity "); shortcutIntent. setComponent (componentName); cut. putExtra (Intent. EXTRA_SHORTCUT_INTENT, shortcutIntent); export cuticonresource iconRes = null; // The shortcut icon iconRes = Intent. using cuticonresource. fromContext (this, R. drawable. shortcut_process_clear_shortcut_icon); shortcut. putExtra (Intent. EXTRA_SHORTCUT_ICON_RESOURCE, iconRes); sendBroadcast (shortcut); Log. I ("AAA", "sendBroadcast: INSTALL_SHORTCUT ");}
The created shortcut does not open figure 1, but opens figure 2.
From the code of the createShortcut () method
ComponentName componentName = new ComponentName(getPackageName(), "com.tang.demo360.CleanActivity");shortcutIntent.setComponent(componentName);
Opened the Activity com. tang. demo360.CleanActivity. But in fact, it is not enough to only do this. We must configure Action for CleanActivity in manifest:
<Action android: name = "android. intent. action. MAIN"/> the two can be used together to directly start CleanActivity.
2. determine the location where CleanActivity is opened
We know that the shortcut is located in different CleanActivity locations. When you click the desktop shortcut to start the Activity, we press "ActivityManager" logcat to find the following information:
Among them, bnds = [510,282] [679,399] seems to be a coordinate. It is found on the Launcher source code:
public void onClick(View v){........Object tag = v.getTag(); if (tag instanceof ShortcutInfo) { // Open shortcut final Intent intent = ((ShortcutInfo) tag).intent; int[] pos = new int[2]; v.getLocationOnScreen(pos); intent.setSourceBounds(new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight())); boolean success = startActivitySafely(intent, tag);......}
When you click a shortcut, the shortcut is uploaded in a Rect.
After the location is obtained, you just need to change the style of the Activity and use the location data to get the above effect.
<style name="MTheme" parent="@android:style/Theme"> <item name="android:windowNoTitle">true</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowIsFloating">true</item> <item name="android:backgroundDimAmount">0</item> </style>
Android: backgroundDimAmount adjusts the background grayscale
Android: Floating wisfloating floating window Indicates floating on the screen. If used here, the entire layout will be in the center of the screen, which is equivalent to floating on the screen.
Rect rect = getIntent().getSourceBounds();rootView = new CleanView(this,rect);setContentView(rootView);WindowManager.LayoutParams lp = getWindow().getAttributes();WindowManager windowManager = getWindowManager();int w = windowManager.getDefaultDisplay().getWidth();int h = windowManager.getDefaultDisplay().getHeight();lp.x = lp.x+(rect.left-w/2)+Value.WIDTH/2;lp.y = lp.y+(rect.top-h/2)+Value.HEIGHT/2;getWindow().setAttributes(lp);
Since the coordinate origin point is also in the center of the screen after the floating window is used, it is different from the left origin of the parameters in the Rect we get, so we need to convert the positional relationship.
Lp. x = lp. x + (rect. left-w/2) + Value. WIDTH/2;
Lp. y = lp. y + (rect. top-h/2) + Value. HEIGHT/2;
3. Implementation of CleanView Layout
To achieve the above effect, CleanView is divided into two parts
Part1.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/shortcut_process_clear_cover"> <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/shortcut_process_clear_fg" /> <com.tang.demo360.view.LevelView android:id="@+id/text0" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:textColor="#ffffff" android:text="10%" android:background="@drawable/task_killer"/></RelativeLayout>
Part2.xml
<? Xml version = "1.0" encoding = "UTF-8"?> <LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: orientation = "vertical" android: gravity = "center"> <TextView android: id = "@ + id/text1" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: text = "0 cleanup processes"/> <TextView android: id = "@ + id/text2" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: text = "release memory 0 M"/> <Button android: id = "@ + id/button" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: text = "set filtering list" android: background = "@ drawable/shortcut_process_clear_wlist"/> </LinearLayout>
Then, based on the shortcut location, determine which part is added to the parent container.
view = new LinearLayout(context);view.setOrientation(LinearLayout.HORIZONTAL);view.setBackgroundResource(R.drawable.shortcut_process_clear_bg);WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);int screenWidth = windowManager.getDefaultDisplay().getWidth();if(Value.WIDTH+rect.left+50>screenWidth){view.addView(view2);view.addView(view1);}else{view.addView(view1);view.addView(view2);}addView(view);
4. CleanView animation implementation
Appearance method: from none to available
Exit mode: from scratch
Animation during cleanup: part1.xml ImageView continues to rotate, and the speed changes from slow to fast and then slows down and finally disappears.
Water Animation: first, the percentage of memory occupied by cleanup is reduced to 0 and then to the current percentage of memory occupied.
The first three are relatively easy to introduce. For water surface animation, there are
Public void updateView (Object [] parm) {text1.setText ("cleanup process" + (Integer) parm [0] + ""); decimalFormat decimalFormat = new DecimalFormat ("0.0"); String temp = decimalFormat. format (parm [1]); text2.setText ("release memory" + temp + "M"); setLevelAnimation (Integer) parm [2]);} public void setLevelAnimation (int level) {ClipDrawable clip = (ClipDrawable) text0.getBackground (); text0.setText (level + "%"); clip. setLevel (level * 100 );}
There are two ways to quickly update the animation effect.
Background of Water Surface
<?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/shortcut_process_clear_level" android:clipOrientation="vertical" android:gravity="bottom"> </clip>
ClipDrawable is used to capture an image fragment from another bitmap. setLevel is used to set the truncation percentage. In the main thread, Timer is used to quickly update this value.
Timer = new Timer ();
Timer. schedule (task, 500, 1 );
task = new TimerTask() {@Overridepublic void run() {// TODO Auto-generated method stubif(isDown){level = (level-Value.V)>=0?(level-Value.V):0;if(level ==0){isDown = false;}}else{level = (level+Value.V)<=newlevel?(level+Value.V):newlevel;}parm[2] =level/100;handler.sendEmptyMessage(Value.UPDATE_VIEW);}};
In this way, you only need to accept the Message Value. UPDATE_VIEW in the main thread and call the updateView () method to achieve the animation effect.
5. Let's kill the process.
I checked some materials online and wrote a tool class.
CleanUtil. java
Package com. tang. util; import java. io. bufferedReader; import java. io. fileReader; import java. io. IOException; import java. lang. reflect. method; import java. util. list; import android. app. activity; import android. app. activityManager; import android. content. context; import android. util. log; public class CleanUtil {// close the currently running process public Object [] killRunnintAppInfo (Context context) {MSaveList mSaveList = new MSaveList (Context. getSharedPreferences ("demo360", Activity. MODE_PRIVATE); List <String> list = mSaveList. load (); ActivityManager mActivityManager = (ActivityManager) context. getSystemService (context. ACTIVITY_SERVICE); List <ActivityManager. runningAppProcessInfo> mRunningProcess = mActivityManager. getRunningAppProcesses (); int appSize = getRunningTasksSize (context); long memory = getUesdMemory (context); for (Activ ItyManager. runningAppProcessInfo amProcess: mRunningProcess) {if (amProcess. processName. equals ("com. tang. demo360 ") | amProcess. processName. startsWith ("system") {Log. d ("AAA", "skip the process that does not kill:" + amProcess. processName); continue;} else {if (isInWhiteList (amProcess. processName, list) {Log. d ("AAA", "skip the process that does not kill:" + amProcess. processName);} else {mActivityManager. killBackgroundProcesses (amProcess. processName); Log. d ("AAA", "Killed process:" + amProcess. processName) ;}} appSize = Math. abs (appSize-getRunningTasksSize (context); memory = Math. abs (memory-getUesdMemory (context); return getRecycleMemoryInfo (context, appSize, memory);} // force stop the process private void forceKillApp (ActivityManager am, String packageName) {Method forceStopPackage = null; try {forceStopPackage = am. getClass (). getDeclaredMethod ("forceStopPackage", String. class); forceS TopPackage. setAccessible (true); forceStopPackage. invoke (am, packageName);} catch (Exception e) {// TODO Auto-generated catch blocke. printStackTrace ();}} /***** data to be transmitted * number of killed processes * Number of released M memory * Current memory percentage * @ param context * @ param appSize * @ param memory * @ return */ private Object [] getRecycleMemoryInfo (Context context, int appSize, long memory) {Object [] pram = new Object [] {0, 0}; if (memory> = 0) {pram [0] = AppSize; pram [1] = (memory/1024.0); pram [2] = getUesdMemoryRate (context);} return pram;} private int getRunningTasksSize (Context context) {ActivityManager am = (ActivityManager) context. getSystemService (context. ACTIVITY_SERVICE); return am. getRunningAppProcesses (). size ();}/*** get all RAM of the device * @ return all memory size, unit: kb */private int getAllMemory () {String filePath = "/proc/meminfo"; int ram = 0; F IleReader fr = null; BufferedReader localBufferedReader = null; try {fr = new FileReader (filePath); localBufferedReader = new BufferedReader (fr, 8192); String line = localBufferedReader. readLine (); int a = line. length ()-3; int B = line. indexOf (''); String str = line. substring (B, a); while (str. substring (0, 1 ). equals ("") {str = str. substring (1, str. length ();} ram = Integer. parseInt (str);} catch (IOExc Eption e) {e. printStackTrace ();} finally {try {fr. close (); localBufferedReader. close ();} catch (Exception e) {// TODO: handle finished tione. printStackTrace () ;}} return ram;}/*** get the available RAM of the device * @ return all memory size, unit: kb */private long getAvailMemory (Context context) {ActivityManager am = (ActivityManager) context. getSystemService (Context. ACTIVITY_SERVICE); ActivityManager. memoryInfo mi = new ActivityManager. MemoryInfo (); am. getMemoryInfo (mi); return mi. availMem/1024;}/*** get the memory used by the device * @ return all memory size, unit: kb */private long getUesdMemory (Context context) {return getAllMemory () -getAvailMemory (context);} public int getUesdMemoryRate (Context context) {return (int) (getUesdMemory (context) * 100/getAvailMemory (context ));} /*** determine whether the whitelist is in use * @ param pkg * @ param list * @ return */private boolean isInWhiteList (St Ring pkg, List <String> list) {boolean inOrNot = false; if (list! = Null) {for (int I = 0; I <list. size (); I ++) {if (pkg. equals (list. get (I) {inOrNot = true; break ;}}return inOrNot ;}}
When CleanActivity is started, CleanService is started in onCreate, which implements the Runnable interface
public class CleanService extends Service implements Runnable{.....@Overridepublic void run() {// TODO Auto-generated method stubhandler.sendEmptyMessage(Value.BEGIN_CLEAN);Object [] pram = cleanUtil.killRunnintAppInfo(this);Message message = new Message();message.obj = pram;message.what = Value.UPDATE;handler.sendMessage(message);}@Overridepublic void onCreate() {// TODO Auto-generated method stubif(CleanActivity.local!=null){handler = CleanActivity.local.getHandler();new Thread(this).start();cleanUtil = new CleanUtil();}super.onCreate();}....}
Put the killing process in the background.
Of course, killing a process also requires permissions:
<Uses-permission android: name = "android. permission. KILL_BACKGROUND_PROCESSES"/>
This is the first part. The second part analyzes the whitelist processing.
Due to limited technical skills, the level of writing articles is even more limited. If you have any mistakes, please correct me.
360 one-click cleanup of the cache where other people's computers are available. At the beginning, the icon is like a 360 software manager.
Oh, you should be talking about the 360 software assistant, right? Install the latest 360 security guard version.
Why is one-click cleanup of system garbage and a pile of garbage cleaned up with 360?
360 clear some zero-point files during cleanup. one-click cleanup is to delete things that are suspected to be useless, such as things that you have never used for a long time, but they are useful. So it is best not to use one-click cleanup