Android添加系统级顶层窗口 和 WindowManager添加view的动画问题
当Dialog有编辑框时如果选择会弹菜单窗口就不要用
Context applicationContext = mainActivity.getApplicationContext();
AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(applicationContext);
AlertDialog dialog = dlgBuilder.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
public class Dialog implements DialogInterface, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener
constructor
/**
* Create a Dialog window that uses the default dialog frame style.
*
* @param context The Context the Dialog is to run it. In particular, it
* uses the window manager and theme in this context to
* present its UI.
*/
public Dialog(Context context) {
this(context, 0, true);
} /**
* Create a Dialog window that uses a custom dialog style.
*
* @param context The Context in which the Dialog should run. In particular, it
* uses the window manager and theme from this context to
* present its UI.
* @param theme A style resource describing the theme to use for the
* window. See <a href="{@docRoot}guide/topics/resources/available-resources.html#stylesandthemes">Style
* and Theme Resources</a> for more information about defining and using
* styles. This theme is applied on top of the current theme in
* <var>context</var>. If 0, the default dialog theme will be used.
*/
public Dialog(Context context, int theme) {
this(context, theme, true);
} Dialog(Context context, int theme, boolean createContextThemeWrapper) {
if (createContextThemeWrapper) {
if (theme == 0) {
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(com.android.internal.R.attr.dialogTheme,
outValue, true);
theme = outValue.resourceId;
}
mContext = new ContextThemeWrapper(context, theme);
} else {
mContext = context;
} mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Window w = PolicyManager.makeNewWindow(mContext);
mWindow = w;
w.setCallback(this);
w.setWindowManager(mWindowManager, null, null);
w.setGravity(Gravity.CENTER);
mListenersHandler = new ListenersHandler(this);
}
show
/**
* Start the dialog and display it on screen. The window is placed in the
* application layer and opaque. Note that you should not override this
* method to do initialization when the dialog is shown, instead implement
* that in {@link #onStart}.
*/
public void show() {
if (mShowing) {
if (mDecor != null) {
if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
}
mDecor.setVisibility(View.VISIBLE);
}
return;
} mCanceled = false; if (!mCreated) {
dispatchOnCreate(null);
} onStart();
mDecor = mWindow.getDecorView(); if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
final ApplicationInfo info = mContext.getApplicationInfo();
mWindow.setDefaultIcon(info.icon);
mWindow.setDefaultLogo(info.logo);
mActionBar = new ActionBarImpl(this);
} WindowManager.LayoutParams l = mWindow.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
WindowManager.LayoutParams nl = new WindowManager.LayoutParams();
nl.copyFrom(l);
nl.softInputMode |=
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
l = nl;
} try {
mWindowManager.addView(mDecor, l);
mShowing = true; sendShowMessage();
} finally {
}
}
AndroidRuntime FATAL EXCEPTION
12-28 13:21:19.631: E/AndroidRuntime(8611): FATAL EXCEPTION: main
12-28 13:21:19.631: E/AndroidRuntime(8611): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
12-28 13:21:19.631: E/AndroidRuntime(8611): at android.view.ViewRootImpl.setView(ViewRootImpl.java:571)
12-28 13:21:19.631: E/AndroidRuntime(8611): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:246)
12-28 13:21:19.631: E/AndroidRuntime(8611): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
12-28 13:21:19.631: E/AndroidRuntime(8611): at android.widget.PopupWindow.invokePopup(PopupWindow.java:993)
12-28 13:21:19.631: E/AndroidRuntime(8611): at android.widget.PopupWindow.showAtLocation(PopupWindow.java:847)
12-28 13:21:19.631: E/AndroidRuntime(8611): at com.android.internal.policy.impl.PhoneWindow$DecorView$1.run(PhoneWindow.java:2285)
12-28 13:21:19.631: E/AndroidRuntime(8611): at android.os.Handler.handleCallback(Handler.java:725)
12-28 13:21:19.631: E/AndroidRuntime(8611): at android.os.Handler.dispatchMessage(Handler.java:92)
12-28 13:21:19.631: E/AndroidRuntime(8611): at android.os.Looper.loop(Looper.java:137)
12-28 13:21:19.631: E/AndroidRuntime(8611): at android.app.ActivityThread.main(ActivityThread.java:5041)
12-28 13:21:19.631: E/AndroidRuntime(8611): at java.lang.reflect.Method.invokeNative(Native Method)
12-28 13:21:19.631: E/AndroidRuntime(8611): at java.lang.reflect.Method.invoke(Method.java:511)
12-28 13:21:19.631: E/AndroidRuntime(8611): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
12-28 13:21:19.631: E/AndroidRuntime(8611): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
12-28 13:21:19.631: E/AndroidRuntime(8611): at dalvik.system.NativeStart.main(Native Method)
<!-- Variant of {@link #Theme_Translucent} that has no title bar and
no status bar -->
<style name="Theme.Translucent.NoTitleBar.Fullscreen">
<item name="android:windowFullscreen">true</item>
</style> <!-- Default theme for activities that don't actually display a UI; that
is, they finish themselves before being resumed. -->
<style name="Theme.NoDisplay">
<item name="android:windowBackground">@null</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowDisablePreview">true</item>
<item name="android:windowNoDisplay">true</item>
</style> <!-- Default theme for dialog windows and activities (on API level 10 and lower),
which is used by the
{@link android.app.Dialog} class. This changes the window to be
floating (not fill the entire screen), and puts a frame around its
contents. You can set this theme on an activity if you would like to
make an activity that looks like a Dialog. -->
<style name="Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowTitleStyle">@android:style/DialogWindowTitle</item>
<item name="android:windowBackground">@android:drawable/panel_background</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
<item name="android:windowActionModeOverlay">true</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="textAppearance">@android:style/TextAppearance</item>
<item name="textAppearanceInverse">@android:style/TextAppearance.Inverse</item> <item name="textColorPrimary">@android:color/primary_text_dark</item>
<item name="textColorSecondary">@android:color/secondary_text_dark</item>
<item name="textColorTertiary">@android:color/tertiary_text_dark</item>
<item name="textColorPrimaryInverse">@android:color/primary_text_light</item>
<item name="textColorSecondaryInverse">@android:color/secondary_text_light</item>
<item name="textColorTertiaryInverse">@android:color/tertiary_text_light</item>
<item name="textColorPrimaryDisableOnly">@android:color/primary_text_dark_disable_only</item>
<item name="textColorPrimaryInverseDisableOnly">@android:color/primary_text_light_disable_only</item>
<item name="textColorPrimaryNoDisable">@android:color/primary_text_dark_nodisable</item>
<item name="textColorSecondaryNoDisable">@android:color/secondary_text_dark_nodisable</item>
<item name="textColorPrimaryInverseNoDisable">@android:color/primary_text_light_nodisable</item>
<item name="textColorSecondaryInverseNoDisable">@android:color/secondary_text_light_nodisable</item>
<item name="textColorHint">@android:color/hint_foreground_dark</item>
<item name="textColorHintInverse">@android:color/hint_foreground_light</item>
<item name="textColorSearchUrl">@android:color/search_url_text</item> <item name="textAppearanceLarge">@android:style/TextAppearance.Large</item>
<item name="textAppearanceMedium">@android:style/TextAppearance.Medium</item>
<item name="textAppearanceSmall">@android:style/TextAppearance.Small</item>
<item name="textAppearanceLargeInverse">@android:style/TextAppearance.Large.Inverse</item>
<item name="textAppearanceMediumInverse">@android:style/TextAppearance.Medium.Inverse</item>
<item name="textAppearanceSmallInverse">@android:style/TextAppearance.Small.Inverse</item> <item name="listPreferredItemPaddingLeft">10dip</item>
<item name="listPreferredItemPaddingRight">10dip</item>
<item name="listPreferredItemPaddingStart">10dip</item>
<item name="listPreferredItemPaddingEnd">10dip</item> <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
</style> <!-- Variant of {@link Theme_Dialog} that does not include a frame (or background).
The view hierarchy of the dialog is responsible for drawing all of
its pixels. -->
<style name="Theme.Dialog.NoFrame">
<item name="windowBackground">@android:color/transparent</item>
<item name="android:windowFrame">@null</item>
<item name="windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowCloseOnTouchOutside">false</item>
</style> <!-- Default theme for alert dialog windows (on API level 10 and lower), which is used by the
{@link android.app.AlertDialog} class. This is basically a dialog
but sets the background to empty so it can do two-tone backgrounds. -->
<style name="Theme.Dialog.Alert">
<item name="windowBackground">@android:color/transparent</item>
<item name="windowTitleStyle">@android:style/DialogWindowTitle</item>
<item name="windowContentOverlay">@null</item>
<item name="itemTextAppearance">@android:style/TextAppearance.Large.Inverse</item>
<item name="textAppearanceListItem">@android:style/TextAppearance.Large.Inverse</item>
<item name="textAppearanceListItemSmall">@android:style/TextAppearance.Large.Inverse</item>
</style>
<activity
android:name=".AlertActivity"
android:excludeFromRecents="true"
android:finishOnTaskLaunch="true"
android:launchMode="singleInstance"
android:theme="@*android:style/Theme.Dialog.Alert" >
</activity>
package com.android.autologin; import android.app.Activity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.os.Bundle; /**
* This is the dialog Activity used as an AlertDialog for the user to interact.
* Requires android:launchMode="singleInstance" in your AndroidManifest to work
* properly.
* <p/>
* 当Dialog有编辑框时如果选择会弹菜单窗口就不要用 AlertDialog(Application)
* 再添加WindowManager.LayoutParams. TYPE_SYSTEM_ALERT,
* <pre>
* Context applicationContext = mainActivity.getApplicationContext();
* AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(applicationContext);
* EditText et = new EditText(mainActivity);
* dlgBuilder.setTitle(mainActivity.getTitle());
* dlgBuilder.setPositiveButton(android.R.string.ok, null);
* dlgBuilder.setNegativeButton(android.R.string.cancel, null);
* dlgBuilder.setIcon(android.R.drawable.ic_dialog_alert);
* dlgBuilder.setView(et);
* AlertDialog dialog = dlgBuilder.create();
* dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
* dialog.show();
* </pre>
* 防止报错
* attrs.token = null,
* BadTokenException("Unable to add window -- token " + attrs.token + " is not for an application")
*
* @usage
*
* <i>.java</i>
*
* <code><pre>
* Intent dialogIntent = new Intent(mContext, AlertActivity.class);
* dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
* mContext.startActivity(dialogIntent);
* </pre></code>
*
* <i>AndroidManifest.xml</i>
*
* <pre>
* < activity
* android:name=".AlertActivity"
* android:excludeFromRecents="true"
* android:finishOnTaskLaunch="true"
* android:launchMode="singleInstance"
* android:theme="@android:style/Theme.Dialog" >
* < /activity>
* </pre>
*
* @author Sansan
**/
public class AlertActivity extends Activity implements DialogInterface.OnClickListener, OnDismissListener { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // setContentView(R.layout.alertactivity); // Get root view from current activity
// @see http://stackoverflow.com/questions/4486034/get-root-view-from-current-activity // //rootview
//// check layouts in hierarchyviewer. // findViewById(android.R.id.content) is giving me the root view
// findViewById(android.R.id.content).getRootView()
//getWindow().getDecorView().findViewById(android.R.id.content) // //-------------------------------------------------------------------------------------------
// //This is what I use to get the root view as found in the XML file assigned with setContentView
// //This answer gave the view without the status bar - which is what I wanted. I was looking for
// //the pixel width + height of the visible part of the activity. This one works, thanks!
//
//This excludes ActionBar!
//final ViewGroup viewGroup = (ViewGroup) ((ViewGroup) this.findViewById(android.R.id.content)).getChildAt(0);
// //------------------------------------------------------------------------------------------- // //-------------------------------------------------------------------------------------------
// //I tested this in android 4.0.3, only:
//
// getWindow().getDecorView().getRootView();
//
// //give the same view what we get from
//
// anyview.getRootView(); == com.android.internal.policy.impl.PhoneWindow$DecorView@#########
//
// //and
//
// getWindow().getDecorView().findViewById(android.R.id.content) // //giving child of its == android.widget.FrameLayout@#######
// //Please confirm.
// //------------------------------------------------------------------------------------------- //setVisible(true);
//requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏 // //Error, if select any text to pop up a system menu view, such as
// paste in
// // the Dialog.
// //@see android/view/ViewRootImpl.java
// //case WindowManagerGlobal.ADD_NOT_APP_TOKEN: throw new
// //WindowManager.BadTokenException("Unable to add window -- token " +
// //attrs.token + " is not for an application");
// Context applicationContext = this.getApplicationContext();
// AlertDialog.Builder dlgBuilder = new
// AlertDialog.Builder(applicationContext); //AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(this);
//EditText et = new EditText(this); //dlgBuilder.setTitle(this.getTitle());
//dlgBuilder.setPositiveButton(android.R.string.ok, AlertActivity.this);
//dlgBuilder.setNegativeButton(android.R.string.cancel, AlertActivity.this);
//dlgBuilder.setIcon(android.R.drawable.ic_dialog_alert);
//dlgBuilder.setView(et);
//AlertDialog dialog = dlgBuilder.create();
//dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
//dialog.setCanceledOnTouchOutside(false);
//dialog.setOnDismissListener(this);
//dialog.show(); // //DialogFragment
// FragmentTransaction ft = getFragmentManager().beginTransaction();
// DialogFragment newFragment = MyDialogFragment.newInstance();
// ft.add(android.R.id.content, newFragment);
// ft.commit();
} //// @TargetApi(Build.VERSION_CODES.HONEYCOMB)
// public static class MyDialogFragment extends DialogFragment {
// static MyDialogFragment newInstance() {
// return new MyDialogFragment();
// }
//
// @Override
// public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// //View v = inflater.inflate(R.layout.alertdialog, container, false);
// getActivity().getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
// return new EditText(getActivity());
// }
// } /**
* meanwhile, finish the AlertActivity.
*/
@Override
public void onDismiss(DialogInterface dialog) {
//finish();
} @Override
public void onClick(DialogInterface dialog, int which) { }
}
Context applicationContext = mainActivity.getApplicationContext();
WindowManager applicationWindowManager = (WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE);
AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(mainActivity);
EditText et = new EditText(mainActivity); // Dialog界面
dlgBuilder.setTitle(mainActivity.getTitle());
dlgBuilder.setPositiveButton(android.R.string.ok, null);
dlgBuilder.setNegativeButton(android.R.string.cancel, null);
dlgBuilder.setIcon(android.R.drawable.ic_dialog_alert);
dlgBuilder.setView(et);
AlertDialog dialog = dlgBuilder.create();
// dialog.getWindow().getAttributes().token = mainActivity.getWindow().getAttributes().token;
//
try {
Field mWindowManagerField = Dialog.class.getDeclaredField("mWindowManager");
mWindowManagerField.setAccessible(true);
mWindowManagerField.set(dialog, applicationWindowManager);
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
Alog.w(TAG, e.toString());
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
Alog.w(TAG, e.toString());
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
Alog.w(TAG, e.toString());
} dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
// dialog.getWindow().addFlags(android.R.attr.windowIsFloating);
dialog.show();
public abstract class Window
/**
* Return whether this window is being displayed with a floating style
* (based on the {@link android.R.attr#windowIsFloating} attribute in
* the style/theme).
*
* @return Returns true if the window is configured to be displayed floating
* on top of whatever is behind it.
*/
public abstract boolean isFloating(); /**
* Set the width and height layout parameters of the window. The default
* for both of these is MATCH_PARENT; you can change them to WRAP_CONTENT
* or an absolute value to make a window that is not full-screen.
*
* @param width The desired layout width of the window.
* @param height The desired layout height of the window.
*
* @see ViewGroup.LayoutParams#height
* @see ViewGroup.LayoutParams#width
*/
public void setLayout(int width, int height) {
final WindowManager.LayoutParams attrs = getAttributes();
attrs.width = width;
attrs.height = height;
if (mCallback != null) {
mCallback.onWindowAttributesChanged(attrs);
}
} /**
* Set the gravity of the window, as per the Gravity constants. This
* controls how the window manager is positioned in the overall window; it
* is only useful when using WRAP_CONTENT for the layout width or height.
*
* @param gravity The desired gravity constant.
*
* @see Gravity
* @see #setLayout
*/
public void setGravity(int gravity)
{
final WindowManager.LayoutParams attrs = getAttributes();
attrs.gravity = gravity;
if (mCallback != null) {
mCallback.onWindowAttributesChanged(attrs);
}
} /**
* Set the type of the window, as per the WindowManager.LayoutParams
* types.
*
* @param type The new window type (see WindowManager.LayoutParams).
*/
public void setType(int type) {
final WindowManager.LayoutParams attrs = getAttributes();
attrs.type = type;
if (mCallback != null) {
mCallback.onWindowAttributesChanged(attrs);
}
} /**
* Set the format of window, as per the PixelFormat types. This overrides
* the default format that is selected by the Window based on its
* window decorations.
*
* @param format The new window format (see PixelFormat). Use
* PixelFormat.UNKNOWN to allow the Window to select
* the format.
*
* @see PixelFormat
*/
public void setFormat(int format) {
final WindowManager.LayoutParams attrs = getAttributes();
if (format != PixelFormat.UNKNOWN) {
attrs.format = format;
mHaveWindowFormat = true;
} else {
attrs.format = mDefaultWindowFormat;
mHaveWindowFormat = false;
}
if (mCallback != null) {
mCallback.onWindowAttributesChanged(attrs);
}
} /**
* Specify custom animations to use for the window, as per
* {@link WindowManager.LayoutParams#windowAnimations
* WindowManager.LayoutParams.windowAnimations}. Providing anything besides
* 0 here will override the animations the window would
* normally retrieve from its theme.
*/
public void setWindowAnimations(int resId) {
final WindowManager.LayoutParams attrs = getAttributes();
attrs.windowAnimations = resId;
if (mCallback != null) {
mCallback.onWindowAttributesChanged(attrs);
}
} /**
* Specify an explicit soft input mode to use for the window, as per
* {@link WindowManager.LayoutParams#softInputMode
* WindowManager.LayoutParams.softInputMode}. Providing anything besides
* "unspecified" here will override the input mode the window would
* normally retrieve from its theme.
*/
public void setSoftInputMode(int mode) {
final WindowManager.LayoutParams attrs = getAttributes();
if (mode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
attrs.softInputMode = mode;
mHasSoftInputMode = true;
} else {
mHasSoftInputMode = false;
}
if (mCallback != null) {
mCallback.onWindowAttributesChanged(attrs);
}
} /**
* Convenience function to set the flag bits as specified in flags, as
* per {@link #setFlags}.
* @param flags The flag bits to be set.
* @see #setFlags
* @see #clearFlags
*/
public void addFlags(int flags) {
setFlags(flags, flags);
} /** @hide */
public void addPrivateFlags(int flags) {
setPrivateFlags(flags, flags);
} /**
* Convenience function to clear the flag bits as specified in flags, as
* per {@link #setFlags}.
* @param flags The flag bits to be cleared.
* @see #setFlags
* @see #addFlags
*/
public void clearFlags(int flags) {
setFlags(0, flags);
} /**
* Set the flags of the window, as per the
* {@link WindowManager.LayoutParams WindowManager.LayoutParams}
* flags.
*
* <p>Note that some flags must be set before the window decoration is
* created (by the first call to
* {@link #setContentView(View, android.view.ViewGroup.LayoutParams)} or
* {@link #getDecorView()}:
* {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN} and
* {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}. These
* will be set for you based on the {@link android.R.attr#windowIsFloating}
* attribute.
*
* @param flags The new window flags (see WindowManager.LayoutParams).
* @param mask Which of the window flag bits to modify.
* @see #addFlags
* @see #clearFlags
*/
public void setFlags(int flags, int mask) {
final WindowManager.LayoutParams attrs = getAttributes();
attrs.flags = (attrs.flags&~mask) | (flags&mask);
if ((mask&WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0) {
attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;
}
mForcedWindowFlags |= mask;
if (mCallback != null) {
mCallback.onWindowAttributesChanged(attrs);
}
} private void setPrivateFlags(int flags, int mask) {
final WindowManager.LayoutParams attrs = getAttributes();
attrs.privateFlags = (attrs.privateFlags & ~mask) | (flags & mask);
if (mCallback != null) {
mCallback.onWindowAttributesChanged(attrs);
}
} /**
* Set the amount of dim behind the window when using
* {@link WindowManager.LayoutParams#FLAG_DIM_BEHIND}. This overrides
* the default dim amount of that is selected by the Window based on
* its theme.
*
* @param amount The new dim amount, from 0 for no dim to 1 for full dim.
*/
public void setDimAmount(float amount) {
final WindowManager.LayoutParams attrs = getAttributes();
attrs.dimAmount = amount;
mHaveDimAmount = true;
if (mCallback != null) {
mCallback.onWindowAttributesChanged(attrs);
}
} /**
* Specify custom window attributes. <strong>PLEASE NOTE:</strong> the
* layout params you give here should generally be from values previously
* retrieved with {@link #getAttributes()}; you probably do not want to
* blindly create and apply your own, since this will blow away any values
* set by the framework that you are not interested in.
*
* @param a The new window attributes, which will completely override any
* current values.
*/
public void setAttributes(WindowManager.LayoutParams a) {
mWindowAttributes.copyFrom(a);
if (mCallback != null) {
mCallback.onWindowAttributesChanged(mWindowAttributes);
}
} /**
* Retrieve the current window attributes associated with this panel.
*
* @return WindowManager.LayoutParams Either the existing window
* attributes object, or a freshly created one if there is none.
*/
public final WindowManager.LayoutParams getAttributes() {
return mWindowAttributes;
}
WindowManager.LayoutParams
extends ViewGroup.LayoutParams
implements Parcelable
java.lang.Object | ||
? | android.view.ViewGroup.LayoutParams | |
? | android.view.WindowManager.LayoutParams |
WindowManager.LayoutParams 是 WindowManager 接口的嵌套类;它继承于 ViewGroup.LayoutParams; 它用于向WindowManager描述Window的管理策略。
Window.addFlags(int flag)
final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);//覆盖在屏幕锁之上。
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (!pm.isScreenOn()) {//屏幕时候保持高亮
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
}
一些Flag的介绍
窗口之后的内容变暗。
public static final int FLAG_DIM_BEHIND = 0x00000002;窗口之后的内容变模糊。
public static final int FLAG_BLUR_BEHIND = 0x00000004;不许获得焦点。
不能获得按键输入焦点,所以不能向它发送按键或按钮事件。那些时间将发送给它后面的可以获得焦点的窗口。此选项还会设置FLAG_NOT_TOUCH_MODAL选项。设置此选项,意味着窗口不能与软输入法进行交互,所以它的Z序独立于任何活动的输入法(换句话说,它可以全屏显示,如果需要的话,可覆盖输入法窗口)。要修改这一行为,可参考FLAG_ALT_FOCUSALBE_IM选项。
public static final int FLAG_NOT_FOCUSABLE = 0x00000008;不接受触摸屏事件。
public static final int FLAG_NOT_TOUCHABLE = 0x00000010;当窗口可以获得焦点(没有设置FLAG_NOT_FOCUSALBE选项)时,仍然将窗口范围之外的点设备事件(鼠标、触摸屏)发送给后面的窗口处理。否则它将独占所有的点设备事件,而不管它们是不是发生在窗口范围之内。
public static final int FLAG_NOT_TOUCH_MODAL = 0x00000020;如果设置了这个标志,当设备休眠时,点击触摸屏,设备将收到这个第一触摸事件。
通常第一触摸事件被系统所消耗,用户不会看到他们点击屏幕有什么反应。
public static final int FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040;当此窗口为用户可见时,保持设备常开,并保持亮度不变。
public static final int FLAG_KEEP_SCREEN_ON = 0x00000080;窗口占满整个屏幕,忽略周围的装饰边框(例如状态栏)。此窗口需考虑到装饰边框的内容。
public static final int FLAG_LAYOUT_IN_SCREEN =0x00000100;允许窗口扩展到屏幕之外。
public static final int FLAG_LAYOUT_NO_LIMITS =0x00000200;窗口显示时,隐藏所有的屏幕装饰(例如状态条)。使窗口占用整个显示区域。
public static final int FLAG_FULLSCREEN = 0x00000400;此选项将覆盖FLAG_FULLSCREEN选项,并强制屏幕装饰(如状态条)弹出。
public static final int FLAG_FORCE_NOT_FULLSCREEN =0x00000800;抖动。指的是对半透明的显示方法。又称“点透”。图形处理较差的设备往往用“点透”替代Alpha混合。
public static final int FLAG_DITHER = 0x00001000;不允许屏幕截图。
public static final int FLAG_SECURE = 0x00002000;一种特殊模式,布局参数用于指示显示比例。
public static final int FLAG_SCALED = 0x00004000;当屏幕有可能贴着脸时,这一选项可防止面颊对屏幕造成误操作。
public static final int FLAG_IGNORE_CHEEK_PRESSES = 0x00008000;当请求布局时,你的窗口可能出现在状态栏的上面或下面,从而造成遮挡。当设置这一选项后,窗口管理器将确保窗口内容不会被装饰条(状态栏)盖住。
public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000;反转FLAG_NOT_FOCUSABLE选项。
如果同时设置了FLAG_NOT_FOCUSABLE选项和本选项,窗口将能够与输入法交互,允许输入法窗口覆盖;
如果FLAG_NOT_FOCUSABLE没有设置而设置了本选项,窗口不能与输入法交互,可以覆盖输入法窗口。
public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000;如果你设置了FLAG_NOT_TOUCH_MODAL,那么当触屏事件发生在窗口之外事,可以通过设置此标志接收到一个MotionEvent.ACTION_OUTSIDE事件。注意,你不会收到完整的down/move/up事件,只有第一次down事件时可以收到ACTION_OUTSIDE。
public static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000;当屏幕锁定时,窗口可以被看到。这使得应用程序窗口优先于锁屏界面。可配合FLAG_KEEP_SCREEN_ON选项点亮屏幕并直接显示在锁屏界面之前。可使用FLAG_DISMISS_KEYGUARD选项直接解除非加锁的锁屏状态。此选项只用于最顶层的全屏幕窗口。
public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;请求系统墙纸显示在你的窗口后面。窗口必须是半透明的。
public static final int FLAG_SHOW_WALLPAPER = 0x00100000;窗口一旦显示出来,系统将点亮屏幕,正如用户唤醒设备那样。
public static final int FLAG_TURN_SCREEN_ON = 0x00200000;解除锁屏。只有锁屏界面不是加密的才能解锁。如果锁屏界面是加密的,那么用户解锁之后才能看到此窗口,除非设置了FLAG_SHOW_WHEN_LOCKED选项。
public static final int FLAG_DISMISS_KEYGUARD = 0x00400000;锁屏界面淡出时,继续运行它的动画。
public static final int FLAG_KEEP_SURFACE_WHILE_ANIMATING =0x10000000;以原始尺寸显示窗口。用于在兼容模式下运行程序。
public static final int FLAG_COMPATIBLE_WINDOW = 0x20000000;用于系统对话框。设置此选项的窗口将无条件获得焦点。
public static final int FLAG_SYSTEM_ERROR = 0x40000000;
type 的取值:
应用程序窗口。
public static final int FIRST_APPLICATION_WINDOW = 1;
所有程序窗口的“基地”窗口,其他应用程序窗口都显示在它上面。
public static final int TYPE_BASE_APPLICATION =1;
普通应用功能程序窗口。token必须设置为Activity的token,以指出该窗口属谁。
public static final int TYPE_APPLICATION = 2;
用于应用程序启动时所显示的窗口。应用本身不要使用这种类型。
它用于让系统显示些信息,直到应用程序可以开启自己的窗口。
public static final int TYPE_APPLICATION_STARTING = 3;
应用程序窗口结束。
public static final int LAST_APPLICATION_WINDOW = 99;
子窗口。子窗口的Z序和坐标空间都依赖于他们的宿主窗口。
public static final int FIRST_SUB_WINDOW = 1000;
面板窗口,显示于宿主窗口上层。
public static final int TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW;
媒体窗口,例如视频。显示于宿主窗口下层。
public static final int TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW+1;
应用程序窗口的子面板。显示于所有面板窗口的上层。(GUI的一般规律,越“子”越靠上)
public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW +2;
对话框。类似于面板窗口,绘制类似于顶层窗口,而不是宿主的子窗口。
public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW +3;
媒体信息。显示在媒体层和程序窗口之间,需要实现透明(半透明)效果。(例如显示字幕)
public static final int TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW +4;
子窗口结束。( End of types of sub-windows )
public static final int LAST_SUB_WINDOW = 1999;
系统窗口。非应用程序创建。
public static final int FIRST_SYSTEM_WINDOW = 2000;
状态栏。只能有一个状态栏;它位于屏幕顶端,其他窗口都位于它下方。
public static final int TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW;
搜索栏。只能有一个搜索栏;它位于屏幕上方。
public static final int TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1;
电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。
public static final int TYPE_PHONE = FIRST_SYSTEM_WINDOW+2;
系统提示。它总是出现在应用程序窗口之上。
public static final int TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW +3;
锁屏窗口。
public static final int TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW +4;
信息窗口。用于显示toast。
public static final int TYPE_TOAST = FIRST_SYSTEM_WINDOW +5;
系统顶层窗口。显示在其他一切内容之上。此窗口不能获得输入焦点,否则影响锁屏。
public static final int TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW +6;
电话优先,当锁屏时显示。此窗口不能获得输入焦点,否则影响锁屏。
public static final int TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW +7;
系统对话框。(例如音量调节框)。
public static final int TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW +8;
锁屏时显示的对话框。
public static final int TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW +9;
系统内部错误提示,显示于所有内容之上。
public static final int TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW +10;
内部输入法窗口,显示于普通UI之上。应用程序可重新布局以免被此窗口覆盖。
public static final int TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW +11;
内部输入法对话框,显示于当前输入法窗口之上。
public static final int TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW +12;
墙纸窗口。
public static final int TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW +13;
状态栏的滑动面板。
public static final int TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW +14;
系统窗口结束。
public static final int LAST_SYSTEM_WINDOW = 2999;
关于Window的类型,主要有三种:
1 Application Windows:取值在 FIRST_APPLICATION_WINDOW 和 LAST_APPLICATION_WINDOW 之间。
是通常的、顶层的应用程序窗口。必须将token设置成activity的token。
2 Sub Windows:取值在 FIRST_SUB_WINDOW 和 LAST_SUB_WINDOW 之间。
与顶层窗口相关联,token必须设置为它所附着的宿主窗口的token。
3 System Windows:取值在 FIRST_SYSTEM_WINDOW 和 LAST_SYSTEM_WINDOW 之间。
用于特定的系统功能。它不能用于应用程序,使用时需要特殊权限,在manifest.xml中添加如下声明:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> |
这三种类型的图层顺序是一次增高,即Application Windows在对底层,System Windows在最上层。看到这里我们再来看一下上面的代码,其中这样一句:
mWindowLayoutParams.type = android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; |
Dialog是属于Sub Windows类型的,Toast是System Windows类型
Android WindowManager及其动画问题
来源:wangjinyu501的专栏
一、概述 开发中发现在WindowManager上像在Activity中使用动画效果无效,比如下面的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
ImageView iv = new ImageView( this ); iv.setImageResource(R.drawable.ic_launcher); TranslateAnimation animation = new TranslateAnimation( Animation.ABSOLUTE, 20 , Animation.ABSOLUTE, 300 , Animation.ABSOLUTE, 100 , Animation.ABSOLUTE, 400 ); animation.setDuration( 1000 ); animation.setFillAfter( false ); iv.setAnimation(animation); WindowManager mWindowManager = (WindowManager) this .getSystemService(Context.WINDOW_SERVICE); WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(); mLayoutParams.x = 20 ; mLayoutParams.y = 100 ; mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; mLayoutParams.gravity = Gravity.TOP; mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; mWindowManager.addView(iv, mLayoutParams); animation.start(); |
二、分析 为什么会不执行动画呢,原因在于:the view which is going to be animated must not be directly added to the top window, because top window of android is not a real ViewGroup. so the view must be added to a ViewGroup like FrameLayout first and then this ViewGroup be added to the top window.意思是说动画执行的条件是不能直接添加到最顶层的Window,而是需要一个容器。比如,在xml中定义的控件就可以使用动画。 后来发现一种解决方案是WindowManager.LayoutParams有一个动画属性:windowAnimations,可以这样使用
1
2
3
4
5
6
7
8
9
10
11
|
lp = new WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.RGBA_8888); lp.gravity = Gravity.LEFT |Gravity.TOP; lp.windowAnimations = R.style.anim_view; //动画 wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); wm.addView(view, lp); |
但是,这是对整个View的一个动画,而不是View中某个控件的动画。而且,使用的时候需要在View状态改变的时候才会出现动画效果。比如消失/出现的时候才会有动画效果。因此这个方案也是行不通的。 既然WindowManager不是一个ViewGroup,那么就构造一个容器来装载WindowManager,可以如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
/** * */ package com.kince.apus.widget; import com.kince.apus.R; import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.PixelFormat; import android.os.Handler; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; /** * @author kince * @category Windowmanager在Layout中的应用 * * */ public class GuideLayout extends FrameLayout { private WindowManager wManager; private WindowManager.LayoutParams wmParams; private View addView; private TextView mTextView; private ImageView mImageView; private boolean isAddView; private AnimatorSet mShowAnimatorSet, mHideAnimatorSet; private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { super .handleMessage(msg); switch (msg.what) { case 1 : showAnimator(); break ; default : break ; } }; }; /** * @param context */ public GuideLayout(Context context) { this (context, null ); // TODO Auto-generated constructor stub } /** * @param context * @param attrs */ public GuideLayout(Context context, AttributeSet attrs) { this (context, attrs, 0 ); // TODO Auto-generated constructor stub } /** * @param context * @param attrs * @param defStyle */ public GuideLayout(Context context, AttributeSet attrs, int defStyle) { super (context, attrs, defStyle); addView = LayoutInflater.from(context).inflate(R.layout.guide_layout, this ); mTextView = (TextView) addView.findViewById(R.id.tv); mImageView = (ImageView) addView.findViewById(R.id.iv); mTextView.setVisibility(View.GONE); mImageView.setVisibility(View.GONE); setAnimator(); getWindowManager(context); } /** * @category 实例化WindowManager 初次模拟位置时候使用 * @param context */ private void getWindowManager( final Context context) { wManager = (WindowManager) context.getApplicationContext() .getSystemService(Context.WINDOW_SERVICE); wmParams = new WindowManager.LayoutParams(); wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; wmParams.format = PixelFormat.TRANSPARENT; wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; wmParams.gravity = 17 ; wmParams.width = WindowManager.LayoutParams.MATCH_PARENT; wmParams.height = WindowManager.LayoutParams.MATCH_PARENT; } private void setAnimator() { mShowAnimatorSet = new AnimatorSet(); Animator[] showAnimator = new Animator[ 2 ]; showAnimator[ 0 ] = ObjectAnimator.ofFloat(mTextView, "alpha" , new float [] { 0 .0F, 1 .0F }); showAnimator[ 1 ] = ObjectAnimator.ofFloat(mImageView, "alpha" , new float [] { 0 .0F, 1 .0F }); mShowAnimatorSet.playTogether(showAnimator); mShowAnimatorSet.setDuration(1500l); mHideAnimatorSet = new AnimatorSet(); Animator[] hideAnimator = new Animator[ 2 ]; hideAnimator[ 0 ] = ObjectAnimator.ofFloat(mTextView, "alpha" , new float [] { 1 .0F, 0 .0F }); hideAnimator[ 1 ] = ObjectAnimator.ofFloat(mImageView, "alpha" , new float [] { 1 .0F, 0 .0F }); mHideAnimatorSet.playTogether(hideAnimator); mHideAnimatorSet.setDuration(1500l); } public void showAnimator() { mTextView.setVisibility(View.VISIBLE); mImageView.setVisibility(View.VISIBLE); mShowAnimatorSet.start(); isAddView= true ; } public void hideAnimator() { mHideAnimatorSet.start(); mHideAnimatorSet.addListener( new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animator animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animator animation) { // TODO Auto-generated method stub mTextView.setVisibility(View.INVISIBLE); mImageView.setVisibility(View.INVISIBLE); } @Override public void onAnimationCancel(Animator animation) { // TODO Auto-generated method stub } }); } public void sendMessage() { if (isAddView) { wManager.removeView( this ); mHandler.removeMessages( 1 ); isAddView= false ; } mHandler.sendEmptyMessage( 1 ); wManager.addView( this , wmParams); } } |
这样一来,就可以实现在WindowManager上的动画效果了。其实,造成这种现象的原因在于对AndroidAPI以及其体系的理解不够深刻。忽略了动画执行所需要的基本条件,影射的问题就是考虑问题不够全面。所以,不论开发哪种功能,使用哪个API,前期的规划、调研很重要。知己知彼,仅此而已。
Android添加系统级顶层窗口 和 WindowManager添加view的动画问题的更多相关文章
- 图解Android - Android GUI 系统 (1) - 概论
Android的GUI系统是Android最重要也最复杂的系统之一.它包括以下部分: 窗口和图形系统 - Window and View Manager System. 显示合成系统 - Surfac ...
- android Gui系统之WMS(2)----窗口的添加
Android系统很多,但是最常用的就两类,一类是有系统进场管理的,系统窗口.还有一类就是由应用程序产生的,应用窗口. 1.系统窗口的添加流程 1.1 addStatusBarWindow Phone ...
- Android 实现顶层窗口、浮动窗口(附Demo)
做过Window程序开发的朋友应该都知道,我们要把程序窗口置顶很简单,只要设置一些窗口属性即可.但是到了Android,你无法简单设置一个属性,就让Android的Activity置顶.因为只要有新的 ...
- 图解Android - Android GUI 系统 (2) - 窗口管理 (View, Canvas, Window Manager)
Android 的窗口管理系统 (View, Canvas, WindowManager) 在图解Android - Zygote 和 System Server 启动分析一 文里,我们已经知道And ...
- 使用WindowManager添加View——悬浮窗口的基本原理
Android系统中的“窗口”类型虽然很多,但只有两大类是经常使用的:一是由系统进程管理的,称之为“系统窗口”:第二个就是由应用程序产生的,用于显示UI界面的“应用窗口”.如果大家熟悉WindowMa ...
- Android融合推送MixPush SDK集成多家推送平台,共享系统级推送,杀死APP也能收到推送
消息推送是App运营的重要一环,为了优化消息推送成功率,降低电量和流量消耗,系统级的推送服务显得尤为重要.小米和魅族由此推出了自家的推送平台,在MIUI和Flyme上共享系统级推送服务,让APP在被杀 ...
- Android向系统日历中添加日程事件
转自Android向系统日历中添加日程事件 总结 在项目开发中,我们有预约提醒.定时提醒需求时,可以使用系统日历来辅助提醒: 通过向系统日历中写入事件.设置提醒方式(闹钟),实现到时间自动提醒的功能: ...
- Android系统级技巧合集
Android系统级技巧合集(随时更新) #转载请注明来源# 1.高通骁龙系列查看CPU体质等级 CPU体质,即为CPU在工作频率下的电压.同一批次的CPU体质各有不同,体质越高,代表该颗CPU可在更 ...
- 反射调用android系统级API函数
try { Class<?> mClass = Class.forName("com.android.server.wifi.WifiSettingsStore"); ...
随机推荐
- Android中如何截取字符串中某个字符之前或之后的字符串
代码改变世界 Android中如何截取字符串中某个字符之前或之后的字符串 //截取#之前的字符串 String str = "sdfs#d"; str.substring(0, s ...
- 【bzoj4407】于神之怒加强版 莫比乌斯反演+线性筛
题目描述 给下N,M,K.求 输入 输入有多组数据,输入数据的第一行两个正整数T,K,代表有T组数据,K的意义如上所示,下面第二行到第T+1行,每行为两个正整数N,M,其意义如上式所示. 输出 如题 ...
- (C++一本通)最少转弯问题 (经典搜索)
题目描述 给出一张地图,这张地图被分为n×m(n,m<=100)个方块,任何一个方块不是平地就是高山.平地可以通过,高山则不能.现在你处在地图的(x1,y1)这块平地,问:你至少需要拐几个弯才能 ...
- [转] Makefile 基础 (9) —— Makefile 使用make更新函数库文件
该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客:(最原始版本) http://blog.csdn.net/haoel/article/details/2886 我转自 ...
- Jvm运行时数据区 —— Java虚拟机结构小记
关于jvm虚拟机的文章网上都讲烂了.尤其是jvm运行时数据区的内容. 抱着眼见为实的想法,自己翻了翻JVM规范,花了点时间稍微梳理了一下. 以下是阅读Java虚拟机规范(Java SE 8版)的第二章 ...
- Milk Patterns(poj 3261)
题意:找出出现k次的可重叠的最长子串的长度. /* 求出height数组,二分答案,将height分组,看有没有一组个数大于K. WA了很多遍,最后看别人的题解,发现往字符串后面填了一个0,就可以AC ...
- Introduction to the WinPcap Networking Libraries
Introduction to the WinPcap Networking Libraries use wire shark or fiddler
- 标准C程序设计七---121
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- vue 上传文件 和 下载文件
Vue上传文件,不必使用什么element 的uplaod, 也不用什么npm上找的个人写的包,就用原生的Vue加axios就行了, 废话不多说,直接上代码:html: <input type= ...
- jvm类加载的过程
java类加载过程:加载-->验证-->准备-->解析-->初始化,之后类就可以被使用了.绝大部分情况下是按这 样的顺序来完成类的加载全过程的.但是是有例外的地方,解析也是可以 ...