---------------------------------------------------------------------
Compilation Environment: Android 4.0
Test environment: Android 4.2.2 Simulator
Screen resolution: 480*800
Author: Crazy Cockroach
Attention:
1. Resource collection on the Internet, if there is infringement please contact in time, in order to deal with.
2. The code is for learning communication only. Do not commercialize.
--------------------------------------------------------------------
First upper part:
watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvdgfuz25lbmd3dq==/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/center "height=" 294 "width=" 184 "> |
watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvdgfuz25lbmd3dq==/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/center "height=" 296 "width=" 175 "> |
|
|
"One-click Cleanup" is a desktop icon that displays a view after the icon is clicked. To clean up the animation, then show how many processes were cleaned up, how much memory was freed, and click on "Set Filter List" to launch another activity edit filter list.
Androidmanifest.xml such as the following:
<?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:min sdkversion= "8" android:targetsdkversion= "/> <uses-permission android:name=" Com.android.launcher.permis Sion. Install_shortcut "/> <uses-permission android:name=" Android.permission.KILL_BACKGROUND_PROCESSES "/> < Application android:allowbackup= "true" android:icon= "@drawable/ic_launcher" android:label= "@string/ap P_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 and Roid: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. When clicked, a broadcast Com.android.launcher.action.INSTALL_SHORTCUT is issued to create a shortcut that requires permission
<uses-permission android:name= "Com.android.launcher.permission.INSTALL_SHORTCUT"/>
Figure A figure II
private void CreateShortcut () {Intent shortcut = new Intent ("Com.android.launcher.action.INSTALL_SHORTCUT"); & nbsp //shortcut name String name = Getresources (). getString (R.string.app_name); Shortcut.putextra (Intent.extra_shortcut_name,name); Different meanings repeatedly create Shortcut.putextra ("duplicate", false); Intent shortcutintent = new Intent (); ComponentName componentname = new ComponentName (Getpackagename (), "com.tang.demo360.CleanActivity"); Shortcutintent.setcomponent (componentname); Shortcut.putextra (Intent.extra_shortcut_intent, shortcutintent); Shortcuticonresource iconres=null; //shortcuts icons &N Bsp Iconres = Intent.ShortcutIconResource.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 creation of this shortcut is not to open the diagram interface, but to open the diagram of the second.
From the CreateShortcut () method code, see
ComponentName componentname = new ComponentName (Getpackagename (), "com.tang.demo360.CleanActivity"); Shortcutintent.setcomponent (componentname);
Opened the activity of com.tang.demo360.CleanActivity.
But it's not enough just to do that, we have to configure the action for cleanactivity in manifest:
<action android:name= "Android.intent.action.MAIN"/> The two can be used to start cleanactivity directly.
2. Determine where to open the cleanactivity
We know that the location of the shortcut is different from the location of the cleanactivity. Click the desktop shortcut to start activity. We hit "Activitymanager" Logcat will find for example the following information:
watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvdgfuz25lbmd3dq==/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/center ">
Among: bnds=[510,282][679,399] seems to be a coordinate, to launcher source code on a look found:
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 on the shortcut, it's true. The location of the shortcut is placed in a rect.
We got the location. Then just change some of the style of the activity and use the location data. You can get the 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 Adjusting Background grayscale
Android:windowisfloating suspended form, which means floating on the screen, assuming that it is used here, the entire layout will be in the center of the screen, 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);
Because the coordinate origin is also in the center of the screen after using the suspended window. It's different from the left origin of the parameters in the rect we get, so we need to do a positional relationship transformation.
lp.x = lp.x+ (RECT.LEFT-W/2) +VALUE.WIDTH/2;
LP.Y = lp.y+ (RECT.TOP-H/2) +VALUE.HEIGHT/2;
Implementation of the 3.CleanView layout
To achieve the above effect, divide the cleanview 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 "and roid:orientation= "vertical" android:gravity= "center" > <textview android:id= "@+id/text1" Android:layout_width= "Wrap_content" android:layout_height= "wrap_content" android:text= "cleanup process 0"/> ; <textview android:id= "@+id/text2" android:layout_width= "Wrap_content" Android:layout_h eight= "Wrap_content" android:text= "Free Memory 0M"/> <button android:id= "@+id/button" Android:layout_width= "Wrap_content" android:layout_height= "Wrap_content" android:text= "Set filter List" android:background= "@drawable/shortcut_process_clear_wlist"/></LINEARLAYOUT>
Infer which part is added to the parent container first, based on the position of the shortcut.
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: from None to There
Exit mode: From there to no
Cleanup process Animation: Part1.xml ImageView constantly spinning. The speed slows down and then slows down and finally disappears.
Surface Animation: The height of the percentage of memory that is not cleaned up is reduced to 0 and then to the current percentage of memory
The first three are easier not to introduce, for water animation, in the Cleanview has
public void Updateview (Object [] parm) {Text1.settext ("cleanup process" + (Integer) parm[0]+ "Each");D Ecimalformat decimalformat=new DecimalFormat ("0.0"); String Temp=decimalformat.format (parm[1]); Text2.settext ("Free 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 2 methods responsible for high-speed updates to achieve animation effects.
The background of the water
<?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" >
Use clipdrawable to intercept a picture fragment from another bitmap Setlevel method set Intercept percentage, I use a timer in the main thread to update this value at high speed
Timer = new timer ();
Timer.schedule (Task, 500, 1);
task = new TimerTask () {@Overridepublic void Run () {//TODO auto-generated method stubif (isdown) {level = (LEVEL-VALUE.V) &G T;=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);};
This will only accept the Value.update_view message in the main thread and then call the Updateview () method to animate the effect.
5. Let's kill the process.
For this, I checked some information on the Internet 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 executing 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 ( Activitymanager.runningappprocessinfo amprocess:mrunningprocess) {if (AmProcess.processName.equals (" com.tang.demo360 ") | | AmProcess.processName.startsWith ("System")) {log.d ("AAA", "Skip the process not killed:" + amProcess.processname); continue;} else {if (isinwhitelist (amprocess.processname,list)) {log.d ("AAA", "Skip the process not killed:" + amprocess.processname);} Else{mactivitymanager.killbackgroundprocesses (Amprocess.processname); LOG.D ("AAA", "Kill Process:" +amprocess.processname);}}} AppSize = Math.Abs (appsize-getrunningtaskssize (context)); memory = Math.Abs (memory-getuesdmemory (context)); return Getrecyclememoryinfo (context,appsize,memory);} Force shutdown Process private void Forcekillapp (Activitymanager am, String packagename) {Method forcestoppackage = null;try {forcestop Package = Am.getclass (). Getdeclaredmethod ("Forcestoppackage", String.class); forcestoppackage.setaccessible (true); Forcestoppackage.invoke (AM, PackageName);} catch (Exception e) {//TODO auto-generated catch Blocke.printstacktrace ();} }/** * Data to be sent out * How many processes have been killed * release how many 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,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 for device * @return return all memory size. Units: KB */private int getallmemory () {String FilePath = "/proc/meminfo"; int ram = 0; FileReader 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 (IOException e) {e.printstacktrace ();} finally {try {fr.close (); Localbufferedreader.close ();} catch (Exception e) {//TODO:handle exceptione.printstacktrace ();}} return RAM;} /** * Get the available RAM for the device * @return return full memory size in KB */private long getavailmemory (context context) {Activitymanager am = (activityma Nager) Context.getsystemservice (Context.activity_service); Activitymanager.memoryinfo mi = new Activitymanager.memoryinfo (); Am.getmemoryinfo (MI); return mi.availmem/1024;} /** * Get the Used RAM of the device * @return return full memory size in KB */private long getuesdmemory (context context) {return getallmemory ()-Getavailm Emory (context);} public int Getuesdmemoryrate (context context) {return (int) (Getuesdmemory (context) *100/getavailmemory (context));} /** * Infer if the whitelist * @param pkg * @param list * @return */private boolean isinwhitelist (String 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 you start the cleanactivity. Cleanservice was launched in the OnCreate, and the Runnable interface was implemented with heat.
public class Cleanservice extends Service implements runnable{... @Overridepublic void run () {//TODO auto-generated Meth OD 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 ();} ....}
The work of killing the process is put in the background.
Of course the killing process also requires permission:
<uses-permission android:name= "Android.permission.KILL_BACKGROUND_PROCESSES"/>
This is the first part. Part II Analysis of white list processing
Due to the limited skill level and the limited writing level, if you have any errors, welcome Daniel to amend.
Copyright notice: This article Bo Master original articles, blogs, without consent may not be reproduced.
Copy 3,601 key clean implementations (i)