【转】RxJava应用场景:使用zip操作符等待多个网络请求完成

转载自:RxJava应用场景:使用zip操作符等待多个网络请求完成


假设这样一种场景,我们利用github api开发一个app,在user界面,我既要请求user基本信息,又要列举user下的event数据,为此,我准备使用Retrofit来做网络请求,首先写好interfaces

public interface GitHubUser {
    @GET("users/{user}")
    Observable<JsonObject> getUser(@Path("user") String user);
}
public interface GitHubEvents {
    @GET("users/{user}/events")
    Observable<JsonArray> listEvents(@Path("user") String user);
}

然后定义好我们的两个Observable:

Retrofit repo = new Retrofit.Builder()
        .baseUrl("https://api.github.com")
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build();
Observable<JsonObject> userObservable = repo
        .create(GitHubUser.class)
        .getUser(loginName)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread());
Observable<JsonArray> eventsObservable = repo
        .create(GitHubEvents.class)
        .listEvents(loginName)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread());

分别是userObservable和eventsObservable,很显然的,我们将会需要两次请求。两次就两次嘛,但是这里有个问题。

虽然在后台有两次请求,但是在前台,我们希望用户打开这个页面,然后等待加载,然后显示。用户只有一次等待加载的过程。所以说,我们需要等待这两个请求都返回结果了,再开始显示数据。

怎么办?自己写判断两个都加载已完成的代码吗?逻辑好像也不是很复杂,但是代码看起来就没有那么高大上了啊。

其实既然你都用过了还有,那么直觉上你应该意识到也许RxJava可以解决这个问题。没错,就是RxJava,使用zip操作符。

zip( ):使用一个函数组合多个Observable发射的数据集合,然后再发射这个结果

第一次知道这个操作符是在大头鬼翻译的这篇文章中:深入浅出RxJava四-在Android中使用响应式编程 。

“Retrofit对Observable的支持使得它可以很简单的将多个REST请求结合起来。比如我们有一个请求是获取照片的,还有一个请求是获取元数据的,我们就可以将这两个请求并发的发出,并且等待两个结果都返回之后再做处理:

Observable.zip(
        service.getUserPhoto(id),
        service.getPhotoMetadata(id),
        (photo, metadata) -> createPhotoWithData(photo, metadata))
        .subscribe(photoWithData -> showPhoto(photoWithData));

继续阅读【转】RxJava应用场景:使用zip操作符等待多个网络请求完成

Android 系统配置读写

1、增加配置信息:

adb shell setprop [key] [value]
adb shell setprop persist.isilent.me 123456

2、查看配置信息:

adb shell getprop [key]
adb shell getprop persist.isilent.me

注意:必须采用persist.开头的属性名才能永久保存


参考链接:

Android系统配置文件中的设备信息读写:getprop/setprop

Android属性:所设属性值为何在重起后被清除

RecyclerView设置最大高度、宽度

节选自:RecyclerView设置最大高度、宽度


当RecyclerView属性设置为wrap_content+maxHeight时,maxHeight没有效果。

<android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        ...
        android:layout_height="wrap_content"
        android:maxHeight="300dp"
        ...
/>

查看源码时发现,当RecyclerView的LayoutManager#isAutoMeasureEnabled()返回true时,RecyclerView高度取决于children view的布局高度,并非取决于RecyclerView自身的测量高度。

@Override
protected void onMeasure(int widthSpec, int heightSpec) {
    ...
    if (mLayout.mAutoMeasure) {
        ...
        // now we can get the width and height from the children.
        mLayout.setMeasuredDimensionFromChildren(widthSpec, heightSpec);
        if (mLayout.shouldMeasureTwice()) {
            ...
            // now we can get the width and height from the children.
            mLayout.setMeasuredDimensionFromChildren(widthSpec, heightSpec);
        }
    } else {
      ...
    }
}

解决办法

因此,我们只需要重写LayoutManager的public void setMeasuredDimension(Rect childrenBounds, int wSpec, int hSpec)方法即可为RecyclerView设置最大宽高。

override fun setMeasuredDimension(childrenBounds: Rect, wSpec: Int, hSpec: Int) {
    super.setMeasuredDimension(childrenBounds, wSpec, View.MeasureSpec.makeMeasureSpec(maxHeight, AT_MOST))
}

【转】RecyclerView限制最大高度或宽度

转载自:RecyclerView限制最大高度或宽度


在日常开发中,想直接通过android:maxHeight或android:maxWidth在布局文件中限制RecyclerView的最大高度宽度,是无法实现的。通过自定义RecyclerView,覆盖onMeasure方法。在onMeasure方法内部,当发现自身高度或宽度超过限制的最大高度或宽度,则手动将宽或高设置为期望的最大宽或搞。具体代码实现如下: 继续阅读【转】RecyclerView限制最大高度或宽度

MPAndroid–Android图表之饼图

节选自:MPAndroid–Android图表之饼图


饼图适合在什么地方使用?
饼图主要用于展现不同类别数值相对于总数的占比情况。图中每个分块(扇区)的弧长表示该类别的占比大小,所有分块数据总和为100%。当分块过多,容易造成饼图丑化,建议尽量将饼图分块数量控制在五个以内。当数据类别较多时,可以把较小或不重要的数据合并成第五个模块命名为”其它”。如果各类别都必须全部展示,此时选择柱状图或堆积柱状图或许更合适。

Android目前并没有原生支持的图表Api,所以如果要类似饼图之类的图表,只能自己撸代码或者用别人的轮子。自己撸代码,费时费力,而且容易引入无数的Bug。目前在GitHub比较成熟的的图表库就是MPAndroid,英文水平不错的可以撸文档,或者用Google翻译。
MPAndroid Github地址

【转】Android点击其他任意位置收起软键盘

转载自:Android点击其他任意位置收起软键盘


在Android应用开发中,经常出现这样的需求,用户在输入文字的过程中,可能不想继续输入了,通过滑动或者点击其他位置(除软键盘和EditText以外的任何位置),希望能够自动收回键盘,这个功能可能有些rom会自己实现了,但是大部分还是没有自己实现这个功能的,那么如果我们要自己实现,要如何解决呢?

首先,我们当然要先拦截其他任何的用户触摸屏幕的事件,通过重写Activity的boolean dispatchTouchEvent(MotionEvent ev);可是实现拦截用户的触摸事件。代码如下:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    DisplayUtils.hideInputWhenTouchOtherView(this, ev, getExcludeTouchHideInputViews());
    return super.dispatchTouchEvent(ev);
}

继续阅读【转】Android点击其他任意位置收起软键盘

【转】android中避免进入页面EditText自动弹出软键盘

转载自:android中避免进入页面EditText自动弹出软键盘


  1. 说明
    我们在开发项目的过程中,一定会有这样的需求,就是在刚进入有EditText的页面时,不让软键盘弹出,只有用户自己手动的去触摸EditText输入框时候才让软键盘自动弹出,这样做其实也是提高用户体验,让用户可以切身的体验到这样做的好处,那么接下来我们就来看下在代码中该如何实现这样的需求。
  2. 具体做法
    针对于这样的需求,有2种处理方式:
    2.1 第一种是在清单文件中对应的Activity中配置:

    //stateHidden: 隐藏软键盘
    //adjustPan: 保证控件不会因为输入法的弹出而发生变形
    
    <activity
        android:name=".activity.LoginActivity"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar"
        android:windowSoftInputMode="stateHidden|adjustPan" />

    2.2 第二种是在onCreate()方法中写:

    //避免进入页面EdiText自动弹出软键盘
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

注意:
如果是采用第二种方式的话,建议将这句代码写到BaseActvity或者BaseFragment的基类中,有利于简化代码的书写。

这些年,我所经历的所有面试|写给正在求职的 Androider

节选自:这些年,我所经历的所有面试|写给正在求职的 Androider


面试涉及知识点/体系/书籍推荐

以下是面试中遇到的问题整理,有一些被我整理已被整理成博文,其他的都是我这些年积累的面试笔记,虽然不是很全面,但是已经是我保留的全部了。希望有帮助。

网络相关

设计模式

Android

其他

*排序算法

书籍推荐

  • 《Java编程思想》
  • 《Effective Java》
  • 《突破Java程序员基本功的16门课》
  • 《深入理解Java虚拟机》
  • 《Android高级工程师进阶》
  • 《Android研发录》
  • 《Android开发艺术探索》
  • 《打造高质量Android应用》
  • 《Android应用性能优化》
  • 《安卓内核剖析》
  • 《深入安卓卷1》
  • 《深入安卓卷2》
  • 《Android系统源代码情景分析》
  • 《巧用Gradle构建Android应用》
  • 《Android高薪之路》
  • 《Android群英传》
  • 《程序员修炼之道–从小工到专家》
  • 《代码的未来》
  • 《第一行代码》