最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2018年12月10日 15:00:56   作者:WWGtest  
這篇文章主要為大家詳細(xì)介紹了Android單一實例全局可調(diào)用網(wǎng)絡(luò)加載彈窗,具有一定的參考價值,感興趣的小伙伴們可以參考一下

最近因為項目需求,需要完成一個全局的網(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í)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android使用PhotoView實現(xiàn)圖片雙擊放大單擊退出效果

    Android使用PhotoView實現(xiàn)圖片雙擊放大單擊退出效果

    這篇文章主要為大家詳細(xì)介紹了Android使用PhotoView實現(xiàn)圖片雙擊放大單擊退出效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Android繪制音樂播放器示波器

    Android繪制音樂播放器示波器

    這篇文章主要為大家詳細(xì)介紹了Android繪制音樂播放器示波器的相關(guān)資料,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Android自定義View手勢密碼

    Android自定義View手勢密碼

    這篇文章主要為大家詳細(xì)介紹了Android自定義View手勢密碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • Android開發(fā)實現(xiàn)的自動換圖片、輪播圖效果示例

    Android開發(fā)實現(xiàn)的自動換圖片、輪播圖效果示例

    這篇文章主要介紹了Android開發(fā)實現(xiàn)的自動換圖片、輪播圖效果,涉及Android ImageView及界面布局相關(guān)操作技巧,需要的朋友可以參考下
    2019-03-03
  • Android使用SoundPool播放音效實例

    Android使用SoundPool播放音效實例

    這篇文章主要為大家詳細(xì)介紹了Android使用SoundPool播放音效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • react native android6+拍照閃退或重啟的解決方案

    react native android6+拍照閃退或重啟的解決方案

    android 6+權(quán)限使用的時候需要動態(tài)申請,那么在使用rn的時候要怎么處理拍照權(quán)限問題呢?本文提供的是一攬子rn操作相冊、拍照的解決方案,需要的朋友可以參考下
    2017-11-11
  • Android架構(gòu)組件Room的使用詳解

    Android架構(gòu)組件Room的使用詳解

    Room其實就是一個orm,抽象了SQLite的使用。這篇文章給大家介紹了Android架構(gòu)組件Room的使用詳解,需要的朋友參考下吧
    2017-12-12
  • 使用Android造了個滾輪控件輪子示例

    使用Android造了個滾輪控件輪子示例

    這篇文章主要介紹了使用Android造了個滾輪控件輪子示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • Android圖片描邊效果的實現(xiàn)

    Android圖片描邊效果的實現(xiàn)

    這篇文章主要給大家介紹了Android圖片描邊效果的實現(xiàn),在添加圖片描邊的時候我們用到的是圖片蒙版技術(shù),文中通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • android ListView深入理解

    android ListView深入理解

    在android開發(fā)中ListView是比較常用的組件,它以列表的形式展示具體內(nèi)容,并且能夠根據(jù)數(shù)據(jù)的長度自適應(yīng)顯示。抽空把對ListView的使用做了整理,需要的朋友可以參考下
    2012-11-11

最新評論

凌源市| 红河县| 乌鲁木齐市| 黔东| 宁安市| 天台县| 孝感市| 赤峰市| 临汾市| 南溪县| 宁乡县| 沁阳市| 台中市| 榆社县| 全南县| 湘潭县| 视频| 双流县| 项城市| 怀集县| 洪泽县| 嵊州市| 慈溪市| 名山县| 天峨县| 广丰县| 敦煌市| 长兴县| 晋江市| 曲松县| 武平县| 文化| 侯马市| 天门市| 彰化市| 古丈县| 云林县| 新闻| 顺义区| 沈阳市| 福建省|