代码之家  ›  专栏  ›  技术社区  ›  No Name

检查网络状态时主线程冻结

  •  0
  • No Name  · 技术社区  · 7 年前

    这是我的 InternetUtil 用于检查网络状态:

    public class InternetUtil extends ContextWrapper {
    
        public InternetUtil(Context context) {
            super(context);
        }
    
        public static boolean isOnline(){
            ConnectivityManager cm = (ConnectivityManager) BaseApplication.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);
            assert cm != null;
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork == null) return false;
    
            switch (activeNetwork.getType()) {
                case ConnectivityManager.TYPE_WIFI:
                    if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
                            activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
                            isInternet())
                        return true;
                    break;
                case ConnectivityManager.TYPE_MOBILE:
                    if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
                            activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
                            isInternet())
                        return true;
                    break;
                default:
                    return false;
            }
            return false;
        }
    
        private static boolean isInternet() {
    
            Runtime runtime = Runtime.getRuntime();
            try {
                Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
                int exitValue = ipProcess.waitFor();
                Log.d("", exitValue + "");
                return (exitValue == 0);
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
    
            return false;
        }
    }
    

    这里我使用的是Util:

    if (InternetUtil.isOnline()) {
                BaseDataManager baseDataManager = new BaseDataManager(context);
                profileRepository = new ProfileRepository();
    
                Map<String, String> requestBody = new HashMap<>();
                requestBody.put(Constants.PHONE_KEY, phone);
                requestBody.put(Constants.PASSWORD_KEY, password);
    
                Observable.defer((Callable<ObservableSource<?>>) () -> baseDataManager.signIn(requestBody))
                        .subscribeOn(Schedulers.io())
                        .retryWhen(throwableObservable -> throwableObservable.flatMap((Function<Throwable, ObservableSource<?>>) throwable -> {
                            if (throwable instanceof HttpException) {
                                HttpException httpException = (HttpException) throwable;
    
                                if (httpException.code() == 401) {
                                    return baseDataManager.refreshAccessToken();
                                }
                            }
                            return Observable.error(throwable);
                        }))
                        .subscribe(o -> {
                                    if (o instanceof UserProfile) {
                                        UserProfile userProfile = (UserProfile) o;
    
                                        iLoginView.hideProgress();
                                        if (userProfile.getErrorDetails() != null) {
                                            iLoginView.onSigningInFailure(userProfile.getErrorDetails());
                                        } else {
                                            iLoginView.navigateToMainActivity();
                                            profileRepository.updateUserProfile(userProfile);
                                        }
                                    }
                                },
                                throwable -> {
                                    iLoginView.hideProgress();
                                    iLoginView.onSigningInFailure(throwable.getMessage());
                                });
    
            } else {
                iLoginView.hideProgress();
                iLoginView.showOfflineMessage();
            }
    

    如您所见,Internet状态检查在主线程中进行

    但我想让它在不同的线程中工作。所以我想使用RXJava。

    我尝试了这个,但我不知道如何使用这个Util:

    public class InternetUtil {
        public static Observable<Boolean> isInternetOn(Context context) {
            ConnectivityManager connectivityManager
                    = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            return Observable.just(activeNetworkInfo != null && activeNetworkInfo.isConnected());
        }
    }
    

    告诉我怎么做?

    1 回复  |  直到 7 年前
        1
  •  1
  •   garywzh    7 年前

    您只需将之前的inOnlike()函数包装成一个可观察的。

    public class InternetUtil {
        public static Observable<Boolean> isInternetOn() {
            return Observable.fromCallable(new Callable<Boolean>() {
                @Override
                public boolean call() throws Exception {
                    return isOnline();
                }
            });
        }
    }
    

    然后您可以这样使用它:

    InternetUtil.isInternetOn()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe( new Action1<Boolean>() {
                    @Override
                    public void call(boolean isOnline) {
                        if(isOnline){
                        // your mainthread code here
                        }
                    }
                });
    

    如果要使用flapMap,可能可以使用以下内容:

    InternetUtil.isInternetOn()
                .flatMap((new Func1<Boolean, Observable<UserProfile>>() {
                    @Override
                    public Observable<UserProfile> call(boolean isOn) {
                        if (isOn){
                            return Observable.fromCallable((Callable<ObservableSource<?>>) () -> baseDataManager.signIn(requestBody));
                        } else {
                            return Obserable.error(new Throwable("no internet"));
                        }
                    }
                })
                .retryWhen()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe()