国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

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

Android單一實例全局可調(diào)用網(wǎng)絡(luò)加載彈窗

2019-12-12 00:25:10
字體:
供稿:網(wǎng)友

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

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

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

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

總結(jié)一下遇到的問題:

一、dialog必須依賴activity

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

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

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

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

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

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

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

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

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

想到就去做,經(jīng)過嘗試和優(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)    //設(shè)置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("網(wǎng)絡(luò)加載彈窗", "NetWaitDialogActivity.onDestroy"); }  public static void dismiss(){  Log.d("網(wǎng)絡(luò)加載彈窗", "調(diào)用dismiss()方法");  if (MyActivityManager.getAppManager().isActivityExist(NetWaitDialogActivity.class)){   //結(jié)束指定類名的Activity   Log.d("網(wǎng)絡(luò)加載彈窗", "調(diào)用Activity管理工具結(jié)束Activity");   MyActivityManager.getAppManager().finishActivity(NetWaitDialogActivity.class);  }  else {   Log.d("網(wǎng)絡(luò)加載彈窗", "指定類不存在,調(diào)用備用方法");   if (((Activity)NetWaitDialogContext).isFinishing() || ((Activity)NetWaitDialogContext).isDestroyed()) {    Log.d("網(wǎng)絡(luò)加載彈窗", "網(wǎng)絡(luò)加彈窗不存在");   } else {    Log.d("網(wǎng)絡(luò)加載彈窗", "調(diào)用強(qiáng)制關(guān)閉");    ((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)建透明樣式:

<!-- 網(wǎng)絡(luò)加載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中設(shè)置樣式:

<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());

外部調(diào)用:

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()); } /**  * 獲取當(dāng)前Activity(堆棧中最后一個壓入的)  */ public Activity currentActivity(){  Activity activity=activityStack.lastElement();  return activity; } /**  * 結(jié)束當(dāng)前Activity(堆棧中最后一個壓入的)  */ public void finishActivity(){  Activity activity=activityStack.lastElement();  if(activity!=null){   activity.finish();   activity=null;  } } /**  * 結(jié)束指定的Activity  */ public void finishActivity(Activity activity){  if(activity!=null){   activityStack.remove(activity);   activity.finish();   activity=null;  } } /**  * 結(jié)束指定類名的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; }  /**  * 結(jié)束所有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(); } /**  * 退出應(yīng)用程序  */ 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();  } }}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 葫芦岛市| 东辽县| 京山县| 保山市| 抚远县| 阳西县| 河池市| 长阳| 临泽县| 东海县| 孝感市| 长海县| 巴林右旗| 宿迁市| 镇原县| 衡南县| 博野县| 九寨沟县| 商南县| 巩留县| 达州市| 象州县| 彰武县| 彰化市| 汉阴县| 庆安县| 英超| 密山市| 郸城县| 从江县| 富民县| 鹰潭市| 老河口市| 揭东县| 都兰县| 来凤县| 麟游县| 湖州市| 湖州市| 娄烦县| 德州市|