a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 系統(tǒng) > Android > 正文

Android單一實例全局可調用網絡加載彈窗

2019-10-21 21:34:02
字體:
來源:轉載
供稿:網友

最近因為項目需求,需要完成一個全局的網絡加載彈窗需求,真正完成這個需求之后,感覺最重要的不是結果,而是思維。

我剛開始接到這個需求的時候,第一種想到的方案是 基類加單例。但是實際做起來之后發(fā)現(xiàn),因為單例的原因,你的彈窗只能在第一次創(chuàng)建這個單例的activity中顯示出來。

那么發(fā)現(xiàn)這個問題之后在這個的基礎上改進一下,如果我不用activity的上下文,而是采用類似于Application的一種全局上下文呢?當然,個人能力有限,這種想法就給斃掉了,后來由導師指點,利用service的上下文,dialog的style設置為系統(tǒng)級彈窗,那么這時候就會有一種潛在的情況,如果APP退到后臺的話,加載網絡的時候不管用戶在那個頁面,都會顯示這個彈窗,嚴重影響用戶體驗。

后來把思路又回到起點,需要實現(xiàn)兩個點,一:全局可調用。二:單一實例。

總結一下遇到的問題:

一、dialog必須依賴activity

二、因為單例的原因,dialog只能在第一次創(chuàng)建單例的activity顯示

三、不能使用系統(tǒng)級彈窗

OK,基于這些問題和要求,結合自己所掌握的知識。

dialog必須依賴activity,那我就創(chuàng)建一個activity,專門去承載這個dialog,activity背景設置為透明,效果達到。

這時又會出現(xiàn)新的問題,如果在單例中去開啟這個activity,那么就會有很多dialog對象,違反初衷,如果在單例中創(chuàng)建dialog,那么開啟activity的時候又會有很多intent對象,得不償失。解決方法,創(chuàng)建兩個單例,保證intent對象和dialog對象都保持唯一。

實際測試發(fā)現(xiàn),第一次可以正常顯示,第二次就會崩潰。

原因:當activity被銷毀,又重新創(chuàng)建的時候,上下文會改變。因為單例的原因,你dialog的上下文還是第一次activity被創(chuàng)建時候的上下文,那么你再次調用這個dialog的時候,就會報activity不存在的異常。

到這里似乎沒有辦法解決了。

再次思考這個問題,突然靈光一閃,為什么我非要用dialog呢?我既然已經創(chuàng)建出一個專門承載這個dialog的activity了,而且activity的死活是完全和dialog一致的,那么我為什么還要再去創(chuàng)建一個dialog呢?直接把dialog的布局寫在activity里不行嗎?當外部去創(chuàng)建這個activity的時候直接播放動畫,同時提供一個暴露給外部的關閉方法。而且這樣也能用單例保證這個activity實例的單一性。

想到就去做,經過嘗試和優(yōu)化,問題完美解決。

下面是具體實現(xiàn)代碼:

要顯示的activity:

public class NetWaitDialogActivity extends AppCompatActivity {  @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_net_wait_dialog);  //將Activity實例添加到AppManager的堆棧  MyActivityManager.getAppManager().addActivity(this);   Transparentstatusbar();   SimpleDraweeView netwait_dialog_gif = (SimpleDraweeView) findViewById(R.id.netwait_dialog_gif);  //展示動圖  DraweeController draweeController_phone_wait = Fresco.newDraweeControllerBuilder()    .setAutoPlayAnimations(true)    //設置uri,加載本地的gif資源    .setUri(Uri.parse("res://"+this.getPackageName()+"/"+R.drawable.wait))    .build();  netwait_dialog_gif.setController(draweeController_phone_wait); }  /**  * 透明狀態(tài)欄  */ private void Transparentstatusbar() {  ViewGroup contentFrameLayout = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);  View parentView = contentFrameLayout.getChildAt(0);  if (parentView != null && Build.VERSION.SDK_INT >= 14) {   parentView.setFitsSystemWindows(true);   getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);  } }  @Override protected void onDestroy() {  super.onDestroy();  Log.d("網絡加載彈窗", "NetWaitDialogActivity.onDestroy"); }  public static void dismiss(){  Log.d("網絡加載彈窗", "調用dismiss()方法");  if (MyActivityManager.getAppManager().isActivityExist(NetWaitDialogActivity.class)){   //結束指定類名的Activity   Log.d("網絡加載彈窗", "調用Activity管理工具結束Activity");   MyActivityManager.getAppManager().finishActivity(NetWaitDialogActivity.class);  }  else {   Log.d("網絡加載彈窗", "指定類不存在,調用備用方法");   if (((Activity)NetWaitDialogContext).isFinishing() || ((Activity)NetWaitDialogContext).isDestroyed()) {    Log.d("網絡加載彈窗", "網絡加彈窗不存在");   } else {    Log.d("網絡加載彈窗", "調用強制關閉");    ((Activity)NetWaitDialogContext).finish();   }   } }}

布局文件:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:fresco="http://schemas.android.com/apk/res-auto">   <com.facebook.drawee.view.SimpleDraweeView  android:id="@+id/netwait_dialog_gif"  android:layout_width="360dp"  android:layout_height="100dp"  android:layout_centerInParent="true"  fresco:roundedCornerRadius="20dp"></com.facebook.drawee.view.SimpleDraweeView>  </RelativeLayout>

style.xml中創(chuàng)建透明樣式:

<!-- 網絡加載activity背景 --> <style name="Transparent" parent="Theme.AppCompat.Light.NoActionBar">  <item name="android:windowBackground">@android:color/transparent</item>  <item name="android:windowIsTranslucent">true</item>  <item name="android:windowAnimationStyle">@android:style/Animation</item>  <item name="android:windowNoTitle">true</item> </style>

AndroidManifest.xml中設置樣式:

<activity android:name=".NetWaitDialogActivity"   android:theme="@style/Transparent"></activity>

單例工具類:

public class NetWaitStatusUtils { private static NetWaitStatusUtils instance; private Intent intent; private Context context;  private NetWaitStatusUtils(Context context) {  this.context = context;  intent = new Intent(context, NetWaitDialogActivity.class); }  public static NetWaitStatusUtils getInstance(Context context) {  if (instance == null) {   instance = new NetWaitStatusUtils(context);  }  return instance; }  public void show(){  context.startActivity(intent); }  public void dismiss(){  NetWaitDialogActivity.dismiss(); }}

在基類中獲取實例:

netWaitDialog = NetWaitStatusUtils.getInstance(getApplication());

外部調用:

public class MainActivity extends IActivity {  private Handler handler = new Handler();  @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  Button load = findViewById(R.id.load);  Button gotwo = findViewById(R.id.gotwo);  load.setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    netWaitDialog.show();    handler.postDelayed(new Runnable(){     @Override     public void run() {      netWaitDialog.dismiss();     }    }, 3000);   }  });  gotwo.setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    startActivity(new Intent(MainActivity.this,Main2Activity.class));    finish();   }  }); }  @Override protected int getLayoutId() {  return R.layout.activity_main; }  }

這里還有一點需要注意,就是activity的啟動模式,推薦使用singletask。但是這樣也會有一個弊端,就是它會把自它到棧頂?shù)乃衋ctivity實例都銷毀,具體大家可以自行百度。

我這里是用到一個activity的管理類:

package com.example.a9focus.sxt.base; import android.annotation.TargetApi;import android.app.Activity;import android.app.ActivityManager;import android.content.Context;import android.os.Build;import android.util.Log; import java.util.Stack; /** * Created by HXY on 18-12-1. */ public class MyActivityManager { private static Stack<Activity> activityStack; private static MyActivityManager instance;  private MyActivityManager(){} /**  * 單一實例  */ public static MyActivityManager getAppManager(){  if(instance==null){   instance=new MyActivityManager();  }  return instance; } /**  * 添加Activity到堆棧  */ public void addActivity(Activity activity){  if(activityStack==null){   activityStack=new Stack<Activity>();  }  activityStack.add(activity);  Log.d("MyActivityManager", activityStack.toString()); } /**  * 獲取當前Activity(堆棧中最后一個壓入的)  */ public Activity currentActivity(){  Activity activity=activityStack.lastElement();  return activity; } /**  * 結束當前Activity(堆棧中最后一個壓入的)  */ public void finishActivity(){  Activity activity=activityStack.lastElement();  if(activity!=null){   activity.finish();   activity=null;  } } /**  * 結束指定的Activity  */ public void finishActivity(Activity activity){  if(activity!=null){   activityStack.remove(activity);   activity.finish();   activity=null;  } } /**  * 結束指定類名的Activity  */ public void finishActivity(Class<?> cls){//  try {   for (Activity activity : activityStack) {    if(activity.getClass().equals(cls) ){     finishActivity(activity);    }   }//  }catch (Exception e){//   Log.d("MyActivityManager", "指定類不存在");//  }  }  /**  * 判斷一個Activity 是否存在  *  * @param clz  * @return  */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public boolean isActivityExist(Class<?> clz) {  boolean res;  Activity activity = getActivity(clz);  if (activity!=null)   Log.d("MyActivityManager", "判斷是否存在的Activity實例 --> "+activity.toString());  if (activity == null) {   res = false;  } else {   if (activity.isFinishing() || activity.isDestroyed()) {    res = false;   } else {    res = true;   }  }  Log.d("MyActivityManager", "指定Activity存在狀態(tài)" + res);  return res; }  /**  * 獲得指定activity實例  *  * @param clazz Activity 的類對象  * @return  */ public Activity getActivity(Class<?> clazz) {  Activity returnActivity = null;  for (Activity activity : activityStack) {   if(activity.getClass().equals(clazz) ){    returnActivity = activity;    return returnActivity;   }  }  return null; }  /**  * 結束所有Activity  */ public void finishAllActivity(){  for (int i = 0, size = activityStack.size(); i < size; i++){   if (null != activityStack.get(i)){    activityStack.get(i).finish();   }  }  activityStack.clear(); } /**  * 退出應用程序  */ public void AppExit(Context context) {  try {   finishAllActivity();   ActivityManager activityMgr= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);   activityMgr.restartPackage(context.getPackageName());   System.exit(0);  } catch (Exception e) {   e.printStackTrace();  } }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 在线精品亚洲欧美日韩国产 | 天天在线综合 | 91影院| 国产精品美女一区二区三区四区 | 国产乱精品一区二区三区 | 精品三级 | 污视频网站在线观看免费 | 羞羞视频免费观看 | 日本久久精品视频 | 日本黄a三级三级三级 | 国产一级黄色大片 | 亚洲91在线 | 一区二区在线免费观看 | 天天想天天干 | 亚洲怡红院在线 | 久久精品欧美一区二区三区不卡 | 国产精品久久久久久吹潮 | 欧美成人精品激情在线观看 | 四虎永久地址 | www.国产精品 | 国产免费一区二区三区四区五区 | 黄色毛片在线观看 | 精品美女一区 | 成人精品一区二区三区中文字幕 | 国产精品一区二区精品 | 久久久成人精品视频 | 成人精品视频99在线观看免费 | 久久精品天堂 | 亚洲欧洲一区二区 | 国产高清在线精品一区二区三区 | www.国产视频 | 国产乱老熟视频网88av | 国产a久久精品一区二区三区 | 日韩中文在线 | 黄色在线小视频 | 欧美一区二区三区精品 | 国产精品久久久久久吹潮 | 欧美日韩高清一区二区 | 日韩国产一区 | 免费在线观看av的网站 | 国产成人欧美一区二区三区一色天 |