Parcourir la source

[공통][New] Network error 화면 대신 Alert 으로 처리

hyodong.min il y a 7 ans
Parent
commit
cff25e6137

+ 20 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/model/Model.java

@@ -31,6 +31,7 @@ public abstract class Model extends ViewModel implements ILifeCycle {
 
   private IModelResult listener;
   private Disposable networkDisposable;
+  private Disposable retryDisposable;
   protected INetworkReceiverListener networkListener;
 
   public Model() {
@@ -69,6 +70,11 @@ public abstract class Model extends ViewModel implements ILifeCycle {
       networkDisposable.dispose();
       networkDisposable = null;
     }
+    
+    if (null != retryDisposable) {
+      retryDisposable.dispose();
+      retryDisposable = null;
+    }
   }
 
   protected void onResult(Event event) {
@@ -80,6 +86,20 @@ public abstract class Model extends ViewModel implements ILifeCycle {
     }
   }
 
+  /**
+   * 네트워크 연결 확인.
+   */
+  public void checkNetwork() {
+    retryDisposable = new NetworkWatcher().check(App.getInstance().getContext())
+      .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
+      .subscribe(isConnected -> {
+        Log.i("APP# Model | checkNetwork", "| isConnected: " + isConnected);
+        if (null != networkListener) {
+          networkListener.onChangedConnection(isConnected, 0);
+        }
+      }, Throwable::printStackTrace);
+  }
+
   /**
    * Model 로 부터 결과 값을 전달 받을 수 있는 interface 객체
    *

+ 15 - 8
app/src/main/java/kr/co/zumo/app/lifeplus/model/module/APIModule.java

@@ -11,10 +11,12 @@ import io.reactivex.disposables.Disposable;
 import io.reactivex.functions.Consumer;
 import io.reactivex.plugins.RxJavaPlugins;
 import io.reactivex.schedulers.Schedulers;
+import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.bean.api.LifeplusAPIBean;
 import kr.co.zumo.app.lifeplus.bean.api.RequestBean;
 import kr.co.zumo.app.lifeplus.network.api.ParameterMapper;
 import kr.co.zumo.app.lifeplus.util.AppUtil;
+import kr.co.zumo.app.lifeplus.util.ResourceUtil;
 import kr.co.zumo.app.lifeplus.util.StringUtil;
 
 /**
@@ -27,20 +29,20 @@ import kr.co.zumo.app.lifeplus.util.StringUtil;
  * @history 민효동   [2018. 10. 12.]   [최초 작성]
  * @since 2018. 10. 12.
  */
-public abstract class APIModule<T extends RequestBean, R extends LifeplusAPIBean> implements Disposable {
+public abstract class APIModule<T extends RequestBean, L extends LifeplusAPIBean> implements Disposable {
 
   protected Disposable disposable;
 
   // result
-  public class APIConsumer implements Consumer<R> {
-    private IAPIModuleListener<R> listener;
+  public class APIConsumer implements Consumer<L> {
+    private IAPIModuleListener<L> listener;
 
-    public APIConsumer(IAPIModuleListener<R> listener) {
+    public APIConsumer(IAPIModuleListener<L> listener) {
       this.listener = listener;
     }
 
     @Override
-    public void accept(R resultBean) throws Exception {
+    public void accept(L resultBean) throws Exception {
       trace(resultBean.toJson());
       if (resultBean.isSuccess()) {
         listener.onApiSuccess(resultBean);
@@ -97,6 +99,11 @@ public abstract class APIModule<T extends RequestBean, R extends LifeplusAPIBean
       if (StringUtil.isEmpty(message)) {
         message = e.toString();
       }
+
+      if (AppUtil.isRelease()) {
+        message = ResourceUtil.getString(R.string.network_error_message_detail_dialog);
+      }
+
       listener.onApiError(message);
     }
   }
@@ -125,14 +132,14 @@ public abstract class APIModule<T extends RequestBean, R extends LifeplusAPIBean
    * abstract
    ***********************************/
 
-  protected abstract Single<R> getAPI(T requestBean);
+  protected abstract Single<L> getAPI(T requestBean);
 
 
   /***********************************
    * public
    ***********************************/
 
-  public Disposable call(T requestBean, IAPIModuleListener<R> listener) {
+  public Disposable call(T requestBean, IAPIModuleListener<L> listener) {
     RxJavaPlugins.setErrorHandler(e -> {
       Log.e("APP#  APIModule | call", "| > GLOBAL ERROR ->" + e.getLocalizedMessage());
       new APIErrorConsumer(listener).accept(e);
@@ -141,7 +148,7 @@ public abstract class APIModule<T extends RequestBean, R extends LifeplusAPIBean
     Log.d("APP# APIModule | call", "| <" + requestBean.getClass().getSimpleName() + ">");
     Log.d("APP# APIModule | call", "|" + APIModule.this.getClass().getSimpleName() + " -> " + requestBean.toPrettyJson());
 
-    Single<R> single = getAPI(requestBean);
+    Single<L> single = getAPI(requestBean);
     if (null != single) {
       disposable = single.subscribeOn(Schedulers.io())
         .observeOn(AndroidSchedulers.mainThread())

+ 61 - 9
app/src/main/java/kr/co/zumo/app/lifeplus/view/dialog/AlertDialog.java

@@ -7,6 +7,9 @@ import android.app.Dialog;
 import android.content.DialogInterface;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
+import android.support.annotation.StringRes;
+import android.view.View;
+import android.widget.Button;
 
 import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.view.Event;
@@ -23,32 +26,81 @@ import kr.co.zumo.app.lifeplus.view.Event;
  */
 public class AlertDialog extends TextDialog {
 
-  @Override
-  public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
+
+  protected boolean isCancelable = true;
+  @StringRes
+  protected int positiveButtonLabel = R.string.empty_string;
+
+  /**
+   * 표시할 positiveButtonLabel 지정
+   *
+   * @param stringId
+   */
+  public void setPositiveButtonLabelId(@StringRes int stringId) {
+    this.positiveButtonLabel = stringId;
   }
 
+  /**
+   * back key 가능 여부 설정
+   *
+   * @param cancelable
+   */
   @Override
-  public void onDestroyView() {
-    super.onDestroyView();
+  public void setCancelable(boolean cancelable) {
+    super.setCancelable(cancelable);
+    isCancelable = cancelable;
   }
 
   @NonNull
   @Override
   public Dialog onCreateDialog(Bundle savedInstanceState) {
+    if (positiveButtonLabel == R.string.empty_string) {
+      positiveButtonLabel = R.string.confirm;
+    }
     // Use the Builder class for convenient dialog construction
     android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(getActivity());
     builder.setMessage(text)
-      .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
+      .setPositiveButton(positiveButtonLabel, new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int id) {
+          //
+        }
+      });
+    builder.setCancelable(isCancelable);
+    android.support.v7.app.AlertDialog alert = builder.create();
+    alert.setCancelable(isCancelable);
+    alert.setCanceledOnTouchOutside(isCancelable);
+    // Create the AlertDialog object and return it
+    return alert;
+
+  }
+
+  //onStart() is where dialog.show() is actually called on
+  //the underlying dialog, so we have to do it there or
+  //later in the lifecycle.
+  //Doing it in onResume() makes sure that even if there is a config change
+  //environment that skips onStart then the dialog will still be functioning
+  //properly after a rotation.
+  @Override
+  public void onResume() {
+    super.onResume();
+
+    final android.support.v7.app.AlertDialog d = (android.support.v7.app.AlertDialog) getDialog();
+    if (d != null) {
+      Button positiveButton = d.getButton(Dialog.BUTTON_POSITIVE);
+      positiveButton.setOnClickListener(new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
           if (null != getCustomListener()) {
             getCustomListener().onDialogResult(AlertDialog.this, new Event.Builder(Event.CONFIRM).build());
           }
         }
       });
-    // Create the AlertDialog object and return it
-    return builder.create();
-
+    }
   }
 
+  @Override
+  public void onActivityCreated(Bundle savedInstanceState) {
+    super.onActivityCreated(savedInstanceState);
+
+  }
 }

+ 7 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/view/dialog/TextDialog.java

@@ -3,6 +3,10 @@
  */
 package kr.co.zumo.app.lifeplus.view.dialog;
 
+import android.support.annotation.StringRes;
+
+import kr.co.zumo.app.lifeplus.util.ResourceUtil;
+
 /**
  * TextDialog
  * <pre>
@@ -25,5 +29,8 @@ public abstract class TextDialog extends DialogBase {
   public void setText(String text) {
     this.text = text;
   }
+  public void setText(@StringRes int stringId) {
+    this.text = ResourceUtil.getString(stringId);
+  }
 
 }

+ 29 - 2
app/src/main/java/kr/co/zumo/app/lifeplus/view/presenter/Presenter.java

@@ -11,6 +11,7 @@ import android.util.Log;
 
 import com.google.gson.Gson;
 
+import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.ILifeCycle;
 import kr.co.zumo.app.lifeplus.helper.Helper;
 import kr.co.zumo.app.lifeplus.helper.NavigationBar;
@@ -49,6 +50,7 @@ public abstract class Presenter<M extends Model, V extends IView> implements ILi
   protected V view;
   protected Command command;
   protected DialogBase dialog;
+  protected DialogBase dialogNetwork;
   private LoadingDialog waiter;
 
   public Presenter(M model, V view) {
@@ -287,8 +289,33 @@ public abstract class Presenter<M extends Model, V extends IView> implements ILi
   public void onChangedConnection(boolean isConnected, int type) {
     Log.i("APP# Presenter | onChangedConnection", "| " + this.getClass().getSimpleName() + ", isConnected:" + isConnected);
 
-    if (false == isConnected) {
-      go(ScreenID.NETWORK_ERROR);
+    if (isConnected) {
+      if (null != dialogNetwork) {
+        dialogNetwork.dispose();
+        dialogNetwork = null;
+      }
+    }
+    else {
+      if (null == dialogNetwork) {
+        dialogNetwork = new DialogBuilder<AlertDialog, ICustomDialogListener>(getFragmentManager(), DialogID.CONFIRM)
+          .listener(new ICustomDialogListener<AlertDialog>() {
+            @Override
+            public void onDialogResult(AlertDialog dialog, Event event) {
+              model.checkNetwork();
+            }
+
+            @Override
+            public void onDialogCanceled(AlertDialog dialog) {
+              dialogNetwork = null;
+            }
+          })
+          .attribute(dialog -> {
+            dialog.setCancelable(false);
+            dialog.setText(R.string.network_disconnected_message_detail_dialog);
+            dialog.setPositiveButtonLabelId(R.string.retry);
+          })
+          .show();
+      }
     }
   }