public Toast(Context context) {
mContext = context;
mTN = new TN();
mTN.mY = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.toast_y_offset);
mTN.mGravity = context.getResources().getInteger(
com.android.internal.R.integer.config_toastDefaultGravity);
}
複製代碼
Toast.makeText(this,"吐司",Toast.LENGTH_SHORT).show();
複製代碼
/**
* 吐司工具類 避免點擊屢次致使吐司屢次,最後致使Toast就長時間關閉不掉了
* 注意:這裏若是傳入context會報內存泄漏;傳遞activity..getApplicationContext()
* @param content 吐司內容
*/
private static Toast toast;
@SuppressLint("ShowToast")
public static void showToast(String content) {
checkContext();
if (toast == null) {
toast = Toast.makeText(mApp, content, Toast.LENGTH_SHORT);
} else {
toast.setText(content);
}
toast.show();
}
複製代碼
public Toast(Context context) {
mContext = context;
mTN = new TN();
mTN.mY = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.toast_y_offset);
mTN.mGravity = context.getResources().getInteger(
com.android.internal.R.integer.config_toastDefaultGravity);
}
複製代碼
/**
* schedule handleShow into the right thread
*/
@Override
public void show(IBinder windowToken) {
if (localLOGV) Log.v(TAG, "SHOW: " + this);
mHandler.obtainMessage(0, windowToken).sendToTarget();
}
/**
* schedule handleHide into the right thread
*/
@Override
public void hide() {
if (localLOGV) Log.v(TAG, "HIDE: " + this);
mHandler.post(mHide);
}
複製代碼
/** @hide */
oneway interface ITransientNotification {
void show();
void hide();
}
複製代碼
public void show() {
if (mNextView == null) {
throw new RuntimeException("setView must have been called");
}
//經過AIDL(Binder)通訊拿到NotificationManagerService的服務訪問接口,當前Toast類至關於上面例子的客戶端!!!至關重要!!!
INotificationManager service = getService();
String pkg = mContext.getOpPackageName();
TN tn = mTN;
tn.mNextView = mNextView;
try {
//把TN對象和一些參數傳遞到遠程NotificationManagerService中去
service.enqueueToast(pkg, tn, mDuration);
} catch (RemoteException e) {
// Empty
}
}
複製代碼
//遠程NotificationManagerService的服務訪問接口
private static INotificationManager sService;
static private INotificationManager getService() {
//單例模式
if (sService != null) {
return sService;
}
//經過AIDL(Binder)通訊拿到NotificationManagerService的服務訪問接口
sService = INotificationManager.Stub.asInterface(ServiceManager.getService("notification"));
return sService;
}
複製代碼
synchronized (mToastQueue) {
int callingPid = Binder.getCallingPid();
long callingId = Binder.clearCallingIdentity();
try {
ToastRecord record;
int index;
//判斷是不是系統級別的吐司
if (!isSystemToast) {
index = indexOfToastPackageLocked(pkg);
} else {
index = indexOfToastLocked(pkg, callback);
}
if (index >= 0) {
record = mToastQueue.get(index);
record.update(duration);
record.update(callback);
} else {
//建立一個Binder類型的token對象
Binder token = new Binder();
//生成一個Toast窗口,而且傳遞token等參數
mWindowManagerInternal.addWindowToken(token, TYPE_TOAST, DEFAULT_DISPLAY);
record = new ToastRecord(callingPid, pkg, callback, duration, token);
//添加到吐司隊列之中
mToastQueue.add(record);
//對當前索引從新進行賦值
index = mToastQueue.size() - 1;
}
//將當前Toast所在的進程設置爲前臺進程
keepProcessAliveIfNeededLocked(callingPid);
if (index == 0) {
//若是index爲0,說明當前入隊的Toast在隊頭,須要調用showNextToastLocked方法直接顯示
showNextToastLocked();
}
} finally {
Binder.restoreCallingIdentity(callingId);
}
}
複製代碼
public void handleHide() {
if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + mView);
if (mView != null) {
// note: checking parent() just to make sure the view has
// been added... i have seen cases where we get here when
// the view isn't yet added, so let's try not to crash.
if (mView.getParent() != null) {
if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
mWM.removeViewImmediate(mView);
}
mView = null;
}
}
複製代碼
final boolean isSystemToast = isCallerSystem() || ("android".equals(pkg));
複製代碼
private static boolean isUidSystem(int uid) {
final int appid = UserHandle.getAppId(uid);
return (appid == Process.SYSTEM_UID || appid == Process.PHONE_UID || uid == 0);
}
private static boolean isCallerSystem() {
return isUidSystem(Binder.getCallingUid());
}
複製代碼
//判斷是否有權限
NotificationManagerCompat.from(context).areNotificationsEnabled()
//若是沒有通知權限,則直接跳轉設置中心設置
@SuppressLint("ObsoleteSdkInt")
private static void toSetting(Context context) {
Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= 9) {
localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
} else if (Build.VERSION.SDK_INT <= 8) {
localIntent.setAction(Intent.ACTION_VIEW);
localIntent.setClassName("com.android.settings",
"com.android.setting.InstalledAppDetails");
localIntent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName());
}
context.startActivity(localIntent);
}
複製代碼
//初始化
ToastUtils.init(this);
//能夠自由設置吐司的背景顏色,默認是純黑色
ToastUtils.setToastBackColor(this.getResources().getColor(R.color.color_7f000000));
//直接設置最簡單吐司,只有吐司內容
ToastUtils.showRoundRectToast("自定義吐司");
//設置吐司標題和內容
ToastUtils.showRoundRectToast("吐司一下","他發的撒經濟法的解放軍");
//第三種直接設置自定義佈局的吐司
ToastUtils.showRoundRectToast(R.layout.view_layout_toast_delete);
//或者直接採用bulider模式建立
ToastUtils.Builder builder = new ToastUtils.Builder(this.getApplication());
builder
.setDuration(Toast.LENGTH_SHORT)
.setFill(false)
.setGravity(Gravity.CENTER)
.setOffset(0)
.setDesc("內容內容")
.setTitle("標題")
.setTextColor(Color.WHITE)
.setBackgroundColor(this.getResources().getColor(R.color.blackText))
.build()
.show();
複製代碼
/**
* 檢查上下文不能爲空,必須先進性初始化操做
*/
private static void checkContext(){
if(mApp==null){
throw new NullPointerException("ToastUtils context is not null,please first init");
}
}
複製代碼
android.view.WindowManager$BadTokenException
Unable to add window -- token android.os.BinderProxy@7f652b2 is not valid; is your activity running?
複製代碼
Toast.makeText(this,"瀟湘劍雨-yc",Toast.LENGTH_SHORT).show();
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
複製代碼
new Thread(new Runnable() {
@Override
public void run() {
ToastUtils.showRoundRectToast("瀟湘劍雨-楊充");
}
}).start();
複製代碼
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
ToastUtils.showRoundRectToast("瀟湘劍雨-楊充");
Looper.loop();
}
}).start();
複製代碼