How to clean up the memory simple Widget and androidwidget on the Android Desktop
How to implement a simple Widget for memory cleanup on the Android Desktop
We often see software similar to and Kingsoft mobile guard with a widget that is displayed on the desktop, showing the size of the existing memory, then we will bring a key function to clean up the memory with one click and kill the background process. How can this function be implemented? Today we are also trying to create a small control with similar functions.
:
I. UI:
Refer to the Google document to first create a class inheritanceAppWidgetProvider
import android.appwidget.AppWidgetProvider;public class MyWidget extends AppWidgetProvider {}
Then declare it in the list file. We must note that AppWidgetProvider is actually BroadcastReceiver, so register it as a receiver. There are other things to note:
<receiver android:name="com.alexchen.widget.MyWidget" > <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/example_appwidget_info" /> </receiver>
Android. appwidget. action. APPWIDGET_UPDATEIt indicates that the receiver can accept an APPWIDGET_UPDATE broadcast, and only this action can be added here.
Android. appwidget. providerIndicates the data provided by the widget provider when the data type is used,Example_appwidget_infoIndicates the parameter configuration file name and location of the widget.
Then, you need to create an xml folder under the res directory and create a configuration file example_appwidget_info.xml in it. The Google document provides many parameters for the example, in fact, there are only four key parameters:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="94dp" android:minHeight="72dp" android:updatePeriodMillis="86400000" android:initialLayout="@layout/example_appwidget"></appwidget-provider>
Where,
MinWidthAnd
MinHeightThis represents the minimum space occupied by the widget. Generally, this space does not need to be too large. If it is too large, a screen may not be able to be put down, google's official document says that a document larger than 4x4 may not be displayed.
UpdatePeriodMillisIt indicates the data update time. Here, 86400000 MS is actually 24 hours. At first, I may see this parameter and wonder if I can set it to a very small value and refresh it multiple times every second ?, In fact,UpdatePeriodMillisFor this parameter,That is to say, it is useless if you set a smaller value. Google sets the minimum update Time of the widget control to 30 minutes, even if it is set to within 30 minutes, the data will be updated at a frequency of 30 minutes.
InitialLayoutThe parameter represents the layout file of the widget space.
The next step is to define a corresponding layout file. We can create a layout file example_appwidget.xml in the layout directory.
<? Xml version = "1.0" encoding = "UTF-8"?> <LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" android: layout_width = "200dp" android: layout_height = "80dp" android: background = "@ android: color/white" android: gravity = "center_vertical" android: orientation = "vertical"> <TextView android: id = "@ + id/TV _widget" android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: gravity = "center" android: text = "widget control test" android: textColor = "@ android: color/black" android: textSize = "15sp"/> <Button android: id = "@ + id/btn_clear" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_gravity = "center_horizontal" android: text = "clear memory" android: textColor = "# ff000000"/> </LinearLayout>
According to the Google documentation, not all layout components can take effect in the preceding layout. The valid components or layout are:
- FrameLayout
- LinearLayout
- RelativeLayout
- GridLayout
- AnalogClock
- Button
- Chronometer
- ImageButton
- ImageView
- ProgressBar
- TextView
- ViewFlipper
- ListView
- GridView
- StackView
- AdapterViewFlipper
So far, a simple widget control has been written. We can drag it to the desktop on the simulator to see the effect:
II. Implementation of functional logic
Most Widget widgets need to update the data shown above under specific circumstances. How can this be implemented, the code above makes it difficult to find that this widget does not actually have an Activity, so the display of This widget is not actually intended for implementation. It is actually displayed by the desktop application, therefore, we cannot directly update the data above it.
Let's look back at the author we wrote above. In fact, there is no way to implement it. In fact, AppWidgetProvider has several important methods:OnReceive,OnUpdate, onDisabled, onEnabled
WhereOnReceiveThe method is the same as the onReceive method of most broadcast receivers. However, the call of the onReceive method is not subject to our decision. It depends on the Host component that displays the widget control, here is the Android desktop application, so we will find that the number and sequence of onReceive calls may be different when the widget control is dragged to the desktop on different mobile phones, this depends on how the Host component is implemented.
Therefore, the onReceive method is of little help to refresh the widget data.
WhileOnUpdateThe method is described as follows:UpdatePeriodMillisParameter Control. After the above analysis, we all know that its minimum cycle is 30 minutes. Therefore, we can set this parameter to 0. In this method, we usually place some functions for starting and updating the data Service, because if the Service for updating data in the background is accidentally stopped, then it will be re-enabled every 30 minutes, so it won't be able to start any longer:
@ Overridepublic void onUpdate (Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) {super. onUpdate (context, appWidgetManager, appWidgetIds); // System. out. println ("onUpdate"); // restart the service at intervals to prevent the Intent intent = new Intent (context, UpdateWidgetService from being restarted after the service is terminated. class); context. startService (intent );}
The following are two important methods:
OnDisabled and onEnabled
We know that widgets can be dragged to the desktop, whileOnEnabledThe method is called once when the first widget is dragged to the desktop,OnDisabledIt will be called once when the last widget is deleted from the desktop. What we need to do isOnEnabledIn this method, enable a service to refresh the widget data.OnDisabledUse in MethodStopServiceTo stop the service.
@ Overridepublic void onDisabled (Context context) {super. onDisabled (context); System. out. println ("onDisabled"); // stop the data refresh service Intent intent = new Intent (context, UpdateWidgetService. class); context. stopService (intent) ;}@ Overridepublic void onEnabled (Context context) {super. onEnabled (context); System. out. println ("onEnabled"); // enable the Intent intent = new Intent (context, UpdateWidgetService. class); context. startService (intent );}
3. data refresh Service
The following tasks are left behind.UpdateWidgetServiceHow to implement this data refresh Service.
The idea here is simple, for example, refreshing the data in the widget every three seconds. There are many ways to regularly execute tasks in Android. We useTimerAndTimerTaskThen we need to care about how to refresh the data in the widget. After all, the data is displayed in the desktop application.
And we need to use an API --AppWidgetManagerIt has an instance method AppWidgetManager. UpdateAppWidget (ComponentNameProvider,RemoteViewsViews)To update the widget data, we all know that if you need to call a method of another application, you need to use a remote call method, the second parameter is RemoteViews, which serves as a bridge between our applications and desktop applications.Views,It will send the data we set to the desktop application to refresh the data on the widget. We need to go through the following steps:
1. Define a RemoteViews instance:
RemoteViews views = new RemoteViews(getPackageName(),R.layout.process_widget);
2. Set the content of views, that is, refresh the data. The method name here will be strange,
RemoteViews. setTextViewText (int viewId, CharSequence text)
ViewId is the child component id in the widget layout file defined earlier, that is, the object of the content to be refreshed. Here is R. id. TV _test. The second parameter is the content to be updated.
3. Define the first parameter ComponentName.ProviderThen, you can call AppWidgetManager.. UpdateAppWidget (ComponentNameProvider,RemoteViewsViews)To update data
If (timer = null & task = null) {// AppWidgetManager object, used to update widget data awm = AppWidgetManager. getInstance (this); timer = new Timer (); task = new TimerTask () {@ Overridepublic void run () {ComponentName provider = new ComponentName (UpdateWidgetService. this, MyWidget. class); // remote view object, which is used as a bridge to transmit data between the original and desktop applications. RemoteViews views = new RemoteViews (getPackageName (), R. layout. example_appwidget); views. setTextViewText (R. id. TV _widget, "content of the data to be refreshed"); awm. updateAppWidget (provider, views); System. out. println ("==== refreshed widget ====");} // set the cycle time timer. schedule (task, 0, 3000 );}
4. Regularly refresh available memory and one-click memory cleanup
To implement this function, we need to change the regularly refreshed content to the amount remaining in the current memory in the above timed refresh data service. Here we will write a tool-class method to return the remaining memory;
In addition, we also need to add a button in the layout file of the widget control, and set the Click Event of the button in the service that updates the widget data, but it is not like the previous click event here, similarly, to apply to the RemoteView object, you must send a broadcast in this click event. The Action is custom. Here we set it:"Com. alexchen. mobilesafeexercise. killall"Then, we need to write another broadcast receiver to receive the broadcast and execute the operation to kill the background process in the onReceive method. Intent cannot be directly used here, because the Action we intend to perform is not executed by ourselves but by other applications (desktop applications), so we need to usePendingIntent.
Service Code for refreshing widget data:
Package com. alexchen. widget. service; import java. util. timer; import java. util. timerTask; import android. app. pendingIntent; import android. app. service; import android. appwidget. appWidgetManager; import android. content. broadcastReceiver; import android. content. componentName; import android. content. context; import android. content. intent; import android. content. intentFilter; import android. OS. IBinder; import andro Id. text. format. formatter; import android. widget. remoteViews; import com. alexchen. widget. myWidget; import com. alexchen. widget. r; import com. alexchen. widget. utils. systemInfoUtils; public class UpdateWidgetService extends Service {private Timer timer; private TimerTask task; private AppWidgetManager awm; @ Overridepublic IBinder onBind (Intent intent) {return null;} @ Overridepublic void onCreate () {super. onCrea Te (); startTimer ();} private void startTimer () {if (timer = null & task = null) {awm = AppWidgetManager. getInstance (this); timer = new Timer (); task = new TimerTask () {@ Overridepublic void run () {ComponentName provider = new ComponentName (UpdateWidgetService. this, MyWidget. class); RemoteViews views = new RemoteViews (getPackageName (), R. layout. example_appwidget); views. setTextViewText (R. id. TV _widget ," Dd "); views. setTextViewText (R. id. TV _widget, "available memory:" + Formatter. formatFileSize (getApplicationContext (), SystemInfoUtils. getAvailableMem (getApplicationContext (); // you can customize a broadcast. Intent intent Intent = new intent (); Intent. setAction ("com. alexchen. mobilesafeexercise. killall "); // describes an action, which is the PendingIntent pendingIntent = PendingIntent executed by another application. getBroadcast (getApplicationContext (), 0, intent, PendingIntent. FLAG_UPDATE_CURRENT); views. setOnClickPendingIntent (R. id. btn_clear, pendingIntent); awm. updateAppWidget (provider, views); System. out. println ("==== refreshed widget ====") ;}}; timer. schedule (task, 0, 3000) ;}@ Overridepublic void onDestroy () {super. onDestroy (); stopTimer (); unregisterReceiver (offReceiver); unregisterReceiver (onReceiver);} private void stopTimer () {if (timer! = Null & task! = Null) {timer. cancel (); task. cancel (); task = null; timer = null ;}}}
Press the button to clear the broadcast receiver of the memory:
Package com. alexchen. widget. extends er; import java. util. list; import android. app. activityManager; import android. app. activityManager. runningAppProcessInfo; import android. content. broadcastReceiver; import android. content. context; import android. content. intent; public class KillAllReceiver extends BroadcastReceiver {@ Overridepublic void onReceive (Context context, Intent intent) {System. out. println ("Custom broadcast message received... start to clean up memory... "); ActivityManager am = (ActivityManager) context. getSystemService (Context. ACTIVITY_SERVICE); List <RunningAppProcessInfo> runningAppProcesses = am. getRunningAppProcesses (); for (RunningAppProcessInfo info: runningAppProcesses) {am. killBackgroundProcesses (info. processName );}}}
Methods for obtaining available memory:
/*** Get the remaining memory available for the mobile phone ** @ param context * Context * @ return */public static long getAvailableMem (context) {ActivityManager am = (ActivityManager) context. getSystemService (Context. ACTIVITY_SERVICE); MemoryInfo outInfo = new MemoryInfo (); am. getMemoryInfo (outInfo); return outInfo. availMem ;}
Ask how to install the widget (android plug-in) in "cell phone memory" and restart the widget.
Maybe it's your software problem. I just packed it in the cell phone memory. I can send it to you .. (This is the weather clock)
How can I create a memory cleanup icon on the desktop for Xiaomi 2 s?
Hi!
In the unlock desktop status, click the menu key, edit mode, and long press the memory cleanup icon on the bottom line to drag it to the blank area of the screen.
A more detailed description of the problem helps netizens understand your troubles and help you solve the problem more accurately. Thank you for your support for Xiaomi mobile phone!
Xiaomi enterprise Platform [Official Certification]