This article was reproduced from: http://blog.csdn.net/stevenhu_223/article/details/8504058
The implementation of the suspended window involves WindowManager (based on 4.0 source code analysis), which is an interface, the implementation class has Windowmanagerimpl,compatmodewrapper (Windowmanagerimpl's inner Class), Localwindowmanager (The Inner Class of window), the relationship between them such as the class diagram:
Windowmanagerimpl:
1. Is the WindowManager implementation class, WindowManager most of the operations are implemented here, but it is not directly called, Instead, they are used as member variables for Localwindowmanager and Windowmanagerimpl.compatmodewrapper.
2. In Windowmanagerimpl, there are 3 array view[],viewroot[],windowmanager.layoutparams[], respectively, to hold the data for each layer.
The most important function of 3.WindowManagerImpl is to manage the view,layoutparams and the correspondence of the Viewroot.
Localwindowmanager:
In the activity class of the source code, there is an important member variable Mwindow (its implementation class is Phonewindow), also has a member variable Mwindowmanager (trace source know it is a localwindowmanager), In Phonewindow, there are also Mwindowmanager member variables with the same name as the activity. And the Mwindowmanager in activity is obtained by initializing the Setwindowmanager function in the window class.
Therefore, the life cycle of the localwindowmanager in activity is less than the life cycle of the activity, And in Activitythread each activity is created, there is an activity corresponding to its localwindowmanager.
Summary of the Localwindowmanager:
1. This class is the inner class of window, the parent class is compatmodewrapper, and the same is the implementation of the WindowManager interface.
2. Each activity has a Mwindowmanager member variable, and the window class also has the corresponding member variable of the same name. The variable is initialized by calling the Setwindowmanager Method of window, which is actually a Localwindowmanger object.
3. It is also said that each generated activity will construct a corresponding localwindowmanger to manage the activity-hosted layer. (The object can be obtained by Activity.getwindowmanager or GetWindow (). Getwindowmanager)
The life cycle of the 4.LocalWindowMangers is less than the life cycle of the activity (because Mwindowmanager is a member variable of window, and Mwindow is a member variable of the activity), so If we add additional layers manually in one localwindowmanager, you should call Localwindowmanager's Removeview before the activity's finish executes, otherwise an exception will be thrown.
Compatmodewrapper:
This class is the important class for implementing the suspended window.
Trace Source:
1.CompatModeWrapper is equivalent to a shell, while the real implementation of most functions is its member variable Mwindowmanager (Windowmanagerimpl Class).
2. The object can be obtained by getapplication (). Getsystemservice (Context.window_service). (Note: If it is only the localwindowmanager of activity that is obtained through Activity.getsystemservice (Context.window_service)).
3. This object was created at the beginning of each process by a static block of code in Contextimpl, which uses a singleton pattern to ensure that each application has only one.
4. The class can be implemented to create a floating window, that is, when exiting the current activity, the view created through the class is still visible, it is a view of the entire application process, surviving in the process, unaffected by the life cycle of the activity.
OK, after a brief introduction to the implementation class of the WindowManager interface above, the next step is to write the app that implements the hover window. Now that we know we can get compatmodewrapper by Getapplication (). Getsystemservice (Context.window_service), then implement the app to add a floating window view. Then, the implementation can be implemented in activity or service (both of which can create important Android components that survive the application process).
The following app code implements the start of a service through the main activity Startup button, and then creates the Add Hover window in the service:
To get Compatmodewrapper, you first have to add the permissions in the application's Androidmanifest.xml file <uses-permission android:name= " Android.permission.SYSTEM_ALERT_WINDOW "/>
The code for Mainactivity is as follows:
public class Mainactivity extends Activity { @Override public void OnCreate (Bundle savedinstancestate) { super.oncreate (savedinstancestate); Setcontentview (R.layout.main);//Gets the Start button, start = (button) Findviewbyid (r.id.start_id); Gets the Remove Buttons button Remove = (Button) Findviewbyid (r.id.remove_id); Bind Listener Start.setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (View v) {//TODO Auto-generated method Stubintent Intent = new Intent (mainactivity.this, fxservice.class);//Start Fxservicestartservice ( Intent); Finish ();}); Remove.setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (View v) {//uninstallapp (" com.phicomm.hu ") Intent Intent = new Intent (mainactivity.this, fxservice.class);//terminating Fxservicestopservice (Intent);}}); }}
The code for Fxservice is as follows:
Package Com.phicomm.hu;import Android.app.service;import Android.content.intent;import Android.graphics.pixelformat;import Android.os.handler;import Android.os.ibinder;import Android.util.Log;import Android.view.gravity;import Android.view.layoutinflater;import Android.view.motionevent;import Android.view.View; Import Android.view.windowmanager;import Android.view.view.onclicklistener;import Android.view.view.ontouchlistener;import Android.view.windowmanager.layoutparams;import Android.widget.Button; Import Android.widget.linearlayout;import Android.widget.toast;public class Fxservice extends Service {//define floating window layout line Arlayout mfloatlayout; Windowmanager.layoutparams Wmparams; Creates a floating window object that sets layout parameters WindowManager Mwindowmanager; Button mfloatview;private static final String TAG = "Fxservice"; @Overridepublic void OnCreate () {//TODO auto-generated Me Thod stubsuper.oncreate (); LOG.I (TAG, "oncreat"); Createfloatview ();} @Overridepublic ibinder onbind (Intent Intent) {//TODO auto-generated MethoD Stubreturn Null;} private void Createfloatview () {wmparams = new windowmanager.layoutparams ();// Gets the Windowmanagerimpl.compatmodewrappermwindowmanager = (WindowManager) getapplication (). GetSystemService ( Getapplication (). Window_service); LOG.I (TAG, "Mwindowmanager--->" + mwindowmanager);//Set window Typewmparams.type = Layoutparams.type_phone; Set the picture format, the effect is transparent Wmparams.format = pixelformat.rgba_8888; Set the floating window not to be focusable (operation that enables operation of other visible windows except floating windows) Wmparams.flags = layoutparams.flag_not_focusable; Adjust the hover window display docked position to the left top wmparams.gravity = Gravity.left | Gravity.top; In the upper left corner of the screen as the origin, set X, y initial value, relative to gravity wmparams.x = 0; Wmparams.y = 0; Set the hover window length-width data wmparams.width = WindowManager.LayoutParams.WRAP_CONTENT; Wmparams.height = WindowManager.LayoutParams.WRAP_CONTENT; /*//Setting the hover window length-width data wmparams.width = 200; Wmparams.height = 80;*/Layoutinflater inflater = Layoutinflater.from (Getapplication ()); //Gets the layout of the floating window view mfloatlayout = (linearlayout) inflater.inflate (r.layout.float_layout, NULL); Add Mfloatlayout Mwindowmanager.addview (Mfloatlayout, wmparams); Floating window button Mfloatview = (button) Mfloatlayout.findviewbyid (r.id.float_id); Mfloatlayout.measure (View.MeasureSpec.makeMeasureSpec (0,view.measurespec.unspecified), View.MeasureSpec.makeMeasureSpec (0, View.MeasureSpec.UNSPECIFIED)); LOG.I (TAG, "WIDTH/2--->" + mfloatview.getmeasuredwidth ()/2); LOG.I (TAG, "HEIGHT/2--->" + mfloatview.getmeasuredheight ()/2); Set the touch move mfloatview.setontouchlistener (new Ontouchlistener () {@Overridepublic Boolean onTouch (View v) for the Monitor floating window , Motionevent event) {//TODO auto-generated method Stub//getrawx is the coordinate of the touch position relative to the screen, Getx is relative to the button's coordinates wmparams.x = (int) EVENT.GETRAWX ()-Mfloatview.getmeasuredwidth ()/2; LOG.I (TAG, "rawx" + event.getrawx ()); LOG.I (TAG, "X" + event.getx ());//minus 25 is the height of the status bar WMPARAMS.Y = (int) Event.getrawy ()-MfloAtview.getmeasuredheight ()/2-25; LOG.I (TAG, "Rawy" + Event.getrawy ()); LOG.I (TAG, "Y" + event.gety ()); Refresh Mwindowmanager.updateviewlayout (Mfloatlayout, wmparams); return false; You must return false here, otherwise Onclicklistener will not get a listen}}); Mfloatview.setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (View v) {//TODO auto-generated Method Stubtoast.maketext (Fxservice.this, "OnClick", Toast.length_short). Show ();}}); @Overridepublic void OnDestroy () {//TODO auto-generated method Stubsuper.ondestroy (); if (mfloatlayout! = null) {// Remove Suspension window Mwindowmanager.removeview (mfloatlayout);}}}
The layout file for the hover window is r.layout.float_layout, so if we want to design a very beautiful hover window, you can write it in the layout file. Of course, you can also use a custom view to design (haha, teenagers, on this basis to play the imagination it).
The above code is as follows: On the left is the start screen. Clicking on the "Activate Hover window" button will start the background service to create a hover window, while the current activity of the finish, so that a suspended window is created, the window can be moved anywhere, and click on the listener to create a toast prompt (of course, You can also start an activity). To remove a created window, click the Remove Hover Window button, or force the app process to be disabled.
Similarly, the hover view is drawn in an activity, but the following code mostly verifies the views that distinguish between Localwindowmanger and compatmodewrapper additions.
Localwindowmanger can be obtained by Activity.getsystemservice (Context.window_service) or GetWindow (). Getwindowmanager. When we add a view through Localwindowmanger, the activity is exited and the added view disappears.
The verification code is as follows:
Package Com.phicomm.hu;import Android.app.activity;import Android.content.context;import android.content.Intent; Import Android.graphics.pixelformat;import android.os.bundle;import android.util.log;import android.view.Gravity; Import Android.view.layoutinflater;import Android.view.motionevent;import Android.view.view;import Android.view.windowmanager;import Android.view.view.onclicklistener;import Android.view.View.OnTouchListener; Import Android.view.windowmanager.layoutparams;import Android.widget.button;import android.widget.LinearLayout; public class Floatwindowtest extends activity {/** Called when the activity is first created. */private Static final S Tring TAG = "Floatwindowtest"; WindowManager Mwindowmanager; Windowmanager.layoutparams Wmparams; LinearLayout mfloatlayout; Button Mfloatview; @Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Createfloatview (); Setcontentview (R.layout.main);Button start = (Button) Findviewbyid (R.id.start); Button stop = (button) Findviewbyid (r.id.stop); Start.setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (View v) {//TODO auto-generated method Stubcreatefloatview ();//finish ();//handle.post (R);}}); Stop.setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (View v) {//TODO auto-generated method STUBIF (mfloatlayout! = null) {Mwindowmanager.removeview (mfloatlayout); Finish ();}}); } private void Createfloatview () {//Get Layoutparams object wmparams = new Windowmanager.layoutparams (); Gets the Localwindowmanager object Mwindowmanager = This.getwindowmanager (); LOG.I (TAG, "MWindowManager1--->" + this.getwindowmanager ()); Mwindowmanager = GetWindow (). Getwindowmanager (); LOG.I (TAG, "MWindowManager2--->" + GetWindow (). Getwindowmanager ()); Gets the Compatmodewrapper object//Mwindowmanager = (WindowManager) getapplication (). Getsystemservice (Context.window_service); LOG.I (TAG, "MWindowManager3--->" + mwindowmanager); Wmparams.type = Layoutparams.type_phone; Wmparams.format = pixelformat.rgba_8888;; Wmparams.flags = layoutparams.flag_not_focusable; wmparams.gravity = Gravity.left | Gravity.top; wmparams.x = 0; Wmparams.y = 0; Wmparams.width = WindowManager.LayoutParams.WRAP_CONTENT; Wmparams.height = WindowManager.LayoutParams.WRAP_CONTENT; Layoutinflater inflater = This.getlayoutinflater ();//layoutinflater.from (Getapplication ()); Mfloatlayout = (linearlayout) inflater.inflate (r.layout.float_layout, NULL); Mwindowmanager.addview (Mfloatlayout, wmparams); Setcontentview (R.layout.main); Mfloatview = (Button) Mfloatlayout.findviewbyid (r.id.float_id); LOG.I (TAG, "Mfloatview" + Mfloatview); LOG.I (TAG, "mfloatview--parent-->"+ mfloatview.getparent ()); LOG.I (TAG, "mfloatview--parent--parent-->" + mfloatview.getparent (). GetParent ()); Bind Touch Move Monitor Mfloatview.setontouchlistener (new Ontouchlistener () {@Overridepublic Boolean onTouch (View V, Mot Ionevent event) {//TODO auto-generated method stubwmparams.x = (int) event.getrawx ()-Mfloatlayout.getwidth ()/2;// 25 for status bar height wmparams.y = (int) Event.getrawy ()-Mfloatlayout.getheight ()/2-40;mwindowmanager.updateviewlayout ( Mfloatlayout, Wmparams); return false;}); Bind-point-click Listener Mfloatview.setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (View v) {//TODO Auto-generated method Stubintent Intent = new Intent (floatwindowtest.this, Resultactivity.class); StartActivity (Intent );}}); }}
Cancel the above code-related comment section and run the code to view the log information, then you can know the problem (each activity corresponds to a localwindowmanger, each app corresponds to a compatmodewrapper), So to implement a hover window that runs in the app's process, of course, you have to get compatmodewrapper, not localwindowmanger.
Complete code Download link for this article: http://download.csdn.net/detail/stevenhu_223/4996970
Other:
How does a suspended window cover above the taskbar?
The flags add these two: Layoutparams.flag_fullscreen.
and Layoutparams.flag_layout_in_screen
。 Then TYPE with Layoutparams.type_system_error. You can do it.
Android hover windows for use WindowManager