1 Star 0 Fork 22

guidebird / MeiZiNews

forked from 江启12 / MeiZiNews 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

2016/4/29

GitHub:https://github.com/qq137712630/MeiZiNews

碗豆夹下载地址:http://www.wandoujia.com/apps/com.ms.meizinewsapplication


#MeiZiNews


#夜间模式:Colorful

问题

RecyclerView的个别item的颜色还是前一个主题的

地址:https://github.com/hehonghui/Colorful/issues/5

最后我在 clearRecyclerViewRecyclerBin下, 增加((RecyclerView) rootView).getRecycledViewPool().clear();`解决了

public class RecyclerViewSetter extends ViewGroupSetter {


    public RecyclerViewSetter(ViewGroup targetView, int resId) {
        super(targetView, resId);
    }

    public RecyclerViewSetter(ViewGroup targetView) {
        super(targetView);
    }

    @Override
    protected void clearRecyclerViewRecyclerBin(View rootView) {
        super.clearRecyclerViewRecyclerBin(rootView);

        ((RecyclerView) rootView).getRecycledViewPool().clear();
    }

    @Override
    public void setValue(Resources.Theme newTheme, int themeId) {

        clearRecyclerViewRecyclerBin(mView);

        // 遍历子元素与要修改的属性,如果相同那么则修改子View的属性
        for (ViewSetter setter : mItemViewSetters) {

            for (int i = 0; i < ((RecyclerView) mView).getAdapter().getItemCount(); i++) {

                View itemView = ((RecyclerView) mView).getChildAt(i);
                if (itemView == null) {
                    continue;
                }

                boolean isBaseAdapterHelper = ((RecyclerView) mView).getChildViewHolder(itemView) instanceof BaseAdapterHelper;

                if (!isBaseAdapterHelper) {
                    continue;
                }

                BaseAdapterHelper baseAdapterHelper = (BaseAdapterHelper) ((RecyclerView) mView).getChildViewHolder(itemView);
                setter.mView = baseAdapterHelper.getView(setter.mViewId);
                int itemId = setter.getViewId();

                if (baseAdapterHelper.getView(itemId) == null) {
                    continue;
                }
                setter.setValue(newTheme, themeId);
            }
        }
    }

}

#RxJava

RxBus-事件总线

按照以下顺序阅读的话,大概就理解如何使用了

  1. 翻译:通过 RxJava 实现一个 Event Bus – RxBus
  2. 当EventBus遇上RxJava
  3. RXBUS入门
  4. 做更好的RxBus:用RxJava实现事件总线(Event Bus)

Subject解读:ReactiveX文档中文翻译

取消订阅

多线程切换

RxJava 使用:给 Android 开发者的 RxJava 详解

图中共有 5 处含有对事件的操作。

由图中可以看出,①和②两处受第一个 subscribeOn() 影响,运行在红色线程;

③和④处受第一个 observeOn() 的影响,运行在绿色线程;

⑤处受第二个 observeOn() 影响,运行在紫色线程;

而第二个 subscribeOn() ,由于在通知过程中线程就被第一个 subscribeOn() 截断,因此对整个流程并没有任何影响。

这里也就回答了前面的问题:当使用了多个 subscribeOn() 的时候,只有第一个 subscribeOn() 起作用。

subscribeOn() 设置影响在它以上的操作,只有第一个 ````subscribeOn`````起效;

observeOn() 设置影响在它以下的操作,直到下一个 observeOn() 设置。


#GreenDAO

联表查询

DbUtil
/**
 * Built SQL for query:
 * SELECT T."_id",T."HTML_ID",T."COLLECT" FROM "COLLECT_ENTITY" T
 * JOIN HTML_ENTITY J1 ON T."HTML_ID"=J1."_id"
 * WHERE J1."URL"=?
 *
 * @param url
 * @return
 */
public List<CollectEntity> queryCollectByhtmlUrl(String url) {
    QueryBuilder<CollectEntity> queryBuilder = collectEntityDao.queryBuilder();
    queryBuilder.join(CollectEntityDao.Properties.Html_id, HtmlEntity.class, HtmlEntityDao.Properties.Id)
            .where(HtmlEntityDao.Properties.Url.eq(url));
    return queryBuilder.list();
}

#Retrofit 使用

Retrofit 2.0 + OkHttp 3.0 配置

##转换器

retrofit RxAndroid+Retrofit环境搭建

转换器可以被添加到支持其他类型。六兄弟模块适应流行的序列化库为您提供方便。 Converters can be added to support other types. Six sibling modules adapt popular serialization libraries for your convenience.

Gson: com.squareup.retrofit2:converter-gson
Jackson: com.squareup.retrofit2:converter-jackson
Moshi: com.squareup.retrofit2:converter-moshi
Protobuf: com.squareup.retrofit2:converter-protobuf
Wire: com.squareup.retrofit2:converter-wire
Simple XML: com.squareup.retrofit2:converter-simplexml
Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars

直接返回String类型需引入:ScalarsConverterFactory.create()

retrofit = new Retrofit.Builder()
		.client(MyOkHttpClient.getMyOkHttpClient().getOkHttpClient())//设置不同的底层网络库
		.baseUrl(strBaseUrl)
		.addConverterFactory(ScalarsConverterFactory.create())//添加 String类型[ Scalars (primitives, boxed, and String)] 转换器
		.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//添加 RxJava 适配器
		.build();

返回Gson类型需引入:GsonConverterFactory.create()

retrofit = new Retrofit.Builder()
		.client(MyOkHttpClient.getMyOkHttpClient().getOkHttpClient())//设置不同的底层网络库
		.baseUrl(strBaseUrl)
		.addConverterFactory(GsonConverterFactory.create())//添加 json 转换器
		.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//添加 RxJava 适配器
		.build();

##Retrofit 结合 RxJava使用

Retrofit 结合 RxJava使用

  1. 添加依赖

    compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
    compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
    
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
    
    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'io.reactivex:rxjava:1.1.0'

    前两个是 Retrofit 和 Gson 的依赖,第三个是 Retrofit 中 RxJava 转换器的依赖,最后两个就是 RxJava 和 Rx Android 的依赖

  2. 编写 API

    使用 RxJava 的情况下,接口文件稍有修改,接口中的方法的返回类型不再是 Call 而是 Observable 类型:

    public interface GitHub {
    
        @GET("/repos/{owner}/{repo}/contributors")
        Call<List<Contributor>> contributors(@Path("owner") String owner,@Path("repo") String repo);
    
        //使用 RxJava 的方法,返回一个 Observable
        @GET("/repos/{owner}/{repo}/contributors")
        Observable<List<Contributor>> RxContributors(@Path("owner") String owner,@Path("repo") String repo);
    }

    结合 RxJava 使用的 接口就定义好了,模型类不需要变动,接下来直接进行网络请求

  3. 网络请求

    使用 RxJava 的 Retrofit 可以直接在 主线程中编写。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl("https://api.github.com")
                .addConverterFactory(GsonConverterFactory.create())//添加 json 转换器
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//添加 RxJava 适配器
                .build();
    
        GitHub gitHub=retrofit.create(GitHub.class);
        gitHub.RxContributors("square","retrofit")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<List<Contributor>>() {
                    @Override
                    public void onCompleted() {
                        Log.i("TAG","onCompleted");
                    }
    
                    @Override
                    public void onError(Throwable e) {
    
                    }
    
                    @Override
                    public void onNext(List<Contributor> contributors) {
                       for (Contributor c:contributors){
                           Log.i("TAG","RxJava-->"+c.getLogin()+"  "+c.getId()+"  "+c.getContributions());
                       }
                    }
                });
    }

##使用Retrofit和Okhttp实现网络缓存。无网读缓存,有网根据过期时间重新请求

okhttp 请求设置官方文档 使用Retrofit和Okhttp实现网络缓存。无网读缓存,有网根据过期时间重新请求 OuNews 新闻:RetrofitManager类下的 initOkHttpClient 方法 okhttp3.X,retrofit:2.0.0-beta4适用

  1. 配置okhttp中的Cache

    OkHttpClient okHttpClient;
    File cacheFile = new File(DemoActivity.this.getCacheDir(), "[缓存目录]");
    Cache cache = new Cache(cacheFile, 1024 * 1024 * 10); //100Mb
    okHttpClient = new OkHttpClient.Builder()
         .cache(cache)
         .build();

    栗子:

    // 完成缓存
    public class MyOkHttpClient {
    
        //设缓存有效期为两天
        protected static final long CACHE_STALE_SEC = 60 * 60 * 24 * 2;
        //查询缓存的Cache-Control设置,为if-only-cache时只查询缓存而不会请求服务器,max-stale可以配合设置缓存失效时间
        protected static final String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CACHE_STALE_SEC;
        //查询网络的Cache-Control设置,头部Cache-Control设为max-age=0时则不会使用缓存而请求服务器
        protected static final String CACHE_CONTROL_NETWORK = "max-age=0";
    
        private String TAG = "MyOkHttpClient";
    
        private OkHttpClient okHttpClient;
        private static MyOkHttpClient myOkHttpClient;
    
        public static MyOkHttpClient getMyOkHttpClient() {
            if (myOkHttpClient == null) {
                myOkHttpClient = new MyOkHttpClient();
    
            }
    
            return myOkHttpClient;
        }
    
        /**
         * 初始化
         *
         * @param mContext
         */
        public void init(final Context mContext) {
    
            if (okHttpClient != null) {
                return;
            }
    
    
            Log.e(TAG, "初始化okHttpClient");
            // 因为BaseUrl不同所以这里Retrofit不为静态,但是OkHttpClient配置是一样的,静态创建一次即可
            File cacheFile = new File(
                    mContext.getCacheDir(),
                    "HttpCache"
            ); // 指定缓存路径
            Cache cache = new Cache(cacheFile, 1024 * 1024 * 100); // 指定缓存大小100Mb
            // 云端响应头拦截器,用来配置缓存策略
            Interceptor rewriteCacheControlInterceptor = new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    if (!NetUtil.isConnected(mContext)) {
                        request = request.newBuilder()
                                .cacheControl(CacheControl.FORCE_CACHE).build();
                        Log.e(TAG, "no network");
                    }
                    Response originalResponse = chain.proceed(request);
                    if (NetUtil.isConnected(mContext)) {
                        //有网的时候读接口上的@Headers里的配置,你可以在这里进行统一的设置
                        String cacheControl = request.cacheControl().toString();
                        return originalResponse.newBuilder()
                                .header("Cache-Control", cacheControl)
                                .removeHeader("Pragma").build();
                    } else {
                        return originalResponse.newBuilder().header("Cache-Control",
                                "public, only-if-cached," + CACHE_STALE_SEC)
                                .removeHeader("Pragma").build();
                    }
                }
            };
            okHttpClient = new OkHttpClient.Builder().cache(cache)
                    .addNetworkInterceptor(rewriteCacheControlInterceptor)
                    .addInterceptor(rewriteCacheControlInterceptor)
                    .connectTimeout(30, TimeUnit.SECONDS).build();
    
        }
    
        public OkHttpClient getOkHttpClient() {
            return okHttpClient;
        }
    
        /**
         * 根据网络状况获取缓存的策略
         *
         * @return
         */
        @NonNull
        public static String getCacheControl(Context mContext) {
            return NetUtil.isConnected(mContext) ? CACHE_CONTROL_NETWORK : CACHE_CONTROL_CACHE;
        }
    
    }
  2. 配置请求头中的cache-control

    //使用 RxJava 的方法,返回一个 Observable
    @Headers("Cache-Control: public, max-age=3600")
    @GET("/repos/{owner}/{repo}/contributors")
    Observable<List<Contributor>> RxContributors(@Path("owner") String owner,@Path("repo") String repo);
  3. 配置请求 Retrofit 设置不同的底层网络库

    Retrofit retrofit = new Retrofit.Builder()
            .client(okHttpClient)
            .baseUrl("https://api.github.com")
            .addConverterFactory(GsonConverterFactory.create())//添加 json 转换器
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//添加 RxJava 适配器
            .build();
  4. 开启打印连接日志

    /**
     * 开启打印连接日志
     * @return
     */
    private HttpLoggingInterceptor getHttpLoggingInterceptor() {
        boolean isDebug= false;//是否开启
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    
        if(isDebug)
        {
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        }
    
    	//开启打印连接日志
        return interceptor;
    }
    
    OkHttpClient.Builder().addInterceptor(getHttpLoggingInterceptor())
    
    okHttpClient = new OkHttpClient.Builder()
            .addInterceptor(getHttpLoggingInterceptor())
            .cache(cache)
            .addNetworkInterceptor(rewriteCacheControlInterceptor)
            .addInterceptor(rewriteCacheControlInterceptor)
            .connectTimeout(30, TimeUnit.SECONDS).build();

Retrofit 如何使用Observable.from发出多条连接的?

参考 ````` MzituImgListModel ````

/**
 * Retrofit 使用Observable.from发出多条连接
 * @param context
 * @param listener
 * @return
 */
@Override
public Subscription loadWeb(final Context context, final OnModelListener<ImgItem> listener) {

    MyStringRetrofit.getMyStringRetrofit().init(context, MeiZiApi.MZITU_API);
    final MzituApi mzituApi = MyStringRetrofit.getMyStringRetrofit().getCreate(MzituApi.class);


    Observable observable = mzituApi.RxImgList(
            MyOkHttpClient.getCacheControl(context),
            imgId,
            page
    ).flatMap(
            new Func1<String, Observable<Integer>>() {

                @Override
                public Observable<Integer> call(String s) {
                    // 第一次请求先请求页数,从而获得要发的链接数

                    Elements mElements = JsoupUtil.getMzituImgPage(s);
                    Elements tempElements = mElements.select("span");
                    String size = tempElements.get(tempElements.size() - 2).text();
                    if (TextUtils.isEmpty(size)) {
                        return null;
                    }

                    ArrayList<Integer> numList = new ArrayList<Integer>();

                    for (int i = 1; i <= Integer.parseInt(size); i++) {
                        numList.add(i);
                    }
                    return Observable.from(numList);
                }
            }
    ).flatMap(
            new Func1<Integer, Observable<String>>() {
                @Override
                public Observable<String> call(Integer integer) {
                //   发出单次网络请求连接
                    return mzituApi.RxImgList(
                            MyOkHttpClient.getCacheControl(context),
                            imgId,
                            integer + ""
                    );
                }
            }
    ).map(
            new Func1<String, ImgItem>() {
                @Override
                public ImgItem call(String s) {
                //   处理每次请问的结果

                    ImgItem img = new ImgItem();
                    Elements mElements = JsoupUtil.getMzituImgItem(s);
                    Element tempElement = mElements.first();

                    img.setImgUrl(tempElement.select("img").attr("src"));
                    img.setUrl(tempElement.select("img").attr("src"));
                    img.setStory_title(tempElement.select("img").attr("alt"));
                    return img;
                }
            }
    );

    return RxJavaUtil.rxIoAndMain(
            observable,
            new Subscriber<ImgItem>() {

                @Override
                public void onCompleted() {
                    listener.onCompleted();
                }

                @Override
                public void onError(Throwable e) {
                    listener.onError(e.toString());
                    DebugUtil.debugLogErr(e, e.toString());
                }

                @Override
                public void onNext(ImgItem imgItem) {
                    listener.onSuccess(imgItem);
                }
            }
    );
}

问题集

其他笔记

@Path:路径

@Query:查询条件,如:

xx=yy

如果有多个查询条件可以使用: @QueryMap ;


#API

##视频直播

通过webview打开HTML5页面用自己的浏览器点直播MP4和M3U8 【M3U8】测试地址及android播放器

###斗鱼

分类

http://www.douyu.com/directory

进入分类

http://www.douyu.com/directory/game/DOTA2?page=2&isAjax=1

HTML5版-房间信息

http://m.douyu.com/html5/live?roomId=73334

{
    "error": 0,
    "msg": "ok",
    "data": {
        "room_id": "73334",
        "tag_name": "DOTA2",
        "room_src": "http://rpic.douyucdn.cn/z1605/01/15/73334_160501151547.jpg",
        "room_name": "重返8000之路!7600",
        "show_status": "1",
        "online": 13126,
        "nickname": "两仪落214",
        "hls_url": "http://hls3a.douyutv.com/live/73334rRfZajWPCGs_550/playlist.m3u8?wsSecret=c52bca967d3b341d878291b7901c800b&wsTime=1462084010",
        "is_pass_player": false,
        "is_ticket": 0
    }
}

熊猫TV

分类:

http://www.panda.tv/cate

分页

http://www.panda.tv/ajax_sort?pageno=1&pagenum=20&classification=lol
http://www.panda.tv/ajax_sort?token=&pageno=2&pagenum=120&classification=lol

房间:

http://www.panda.tv/354095

房间信息

http://room.api.m.panda.tv/index.php?method=room.shareapi&roomid=354095
http://room.api.m.panda.tv/index.php?method=room.shareapi&roomid=354095&callback=jQuery1910274208655487177_1462807801662&_=1462807801663
http://room.api.m.panda.tv/index.php?method=room.recommend&callback=jQuery1910274208655487177_1462807801664&_=1462807801665

妹子图集

// 专题
http://www.mzitu.com/zhuanti

// 首页
http://www.mzitu.com/
http://www.mzitu.com/page/1

// 热门
http://www.mzitu.com/hot
http://www.mzitu.com/hot/page/2

// 推荐
http://www.mzitu.com/best
http://www.mzitu.com/best/page/2

// 性感妹子
http://www.mzitu.com/xinggan
http://www.mzitu.com/xinggan/page/2

// 日本妹子
http://www.mzitu.com/japan
http://www.mzitu.com/japan/page/2

// 台湾妹子
http://www.mzitu.com/taiwan
http://www.mzitu.com/taiwan/page/2

// 清纯
http://www.mzitu.com/mm
http://www.mzitu.com/mm/page/2

// 图集查看
http://www.mzitu.com/{图集ID}/{页数}
http://www.mzitu.com/65054/48

永久免费的基于深度学习的中文在线抽词-PullWord

永久免费的基于深度学习的中文在线抽词-PullWord API 使用

API:

http://103.37.149.178:16888/pullword/get.php?source=清华大学是好学校&param1=0&param2=1

知乎日报

//Zhihu API
public static final String BASE_URL = "http://news-at.zhihu.com/api/4/news/";//日报详情
public static final String NEWS_LATEST = "http://news-at.zhihu.com/api/4/news/latest";//最新日报
public static final String NEWS_BEFORE = "http://news-at.zhihu.com/api/4/news/before/";//指定日期的日报
public static final String SPLASH = "http://news-at.zhihu.com/api/4/start-image/1080*1920";//封面

http://news-at.zhihu.com/api/4/themes // 主题日报列表查看
http://news-at.zhihu.com/api/4/theme/{id} //主题日报内容查看

豆瓣美女

public static String DB_BREAST = "http://www.dbmeinv.com/dbgroup/show.htm?cid=2&pager_offset=";
public static String DB_BUTT = "http://www.dbmeinv.com/dbgroup/show.htm?cid=6&pager_offset=";
public static String DB_SILK = "http://www.dbmeinv.com/dbgroup/show.htm?cid=7&pager_offset=";
public static String DB_LEG = "http://www.dbmeinv.com/dbgroup/show.htm?cid=3&pager_offset=";
public static String DB_RANK="http://www.dbmeinv.com/dbgroup/rank.htm?pager_offset=";

Android开发技术周报

网址

http://androidweekly.cn

例子:

http://androidweekly.cn/page/2/


#MD实践

##侧滑 NavigationView

最快的方法是创一下新的侧滑模块

设置item颜色

代码中:

int[][] states = new int[][] {
        new int[] { android.R.attr.state_selected }, // selected
        new int[] { android.R.attr.state_focused, android.R.attr.state_pressed },  // pressed
        new int[] {  }, // default
};

int[] colors = new int[] {
        0,
        0,
        getColor(newTheme)
};
navigationView.setItemTextColor(new ColorStateList(
        states,
        colors
));

Xml

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    android:background="?attr/root_view_bg"
    app:headerLayout="@layout/nav_header_main"
    app:itemTextColor="?attr/text_color"
    app:menu="@menu/activity_main_drawer" />

##上下拉:SwipeRefreshLayout

头部: CoordinatorLayout CollapsingToolbarLayout

CoordinatorLayout

总结: 为了使得Toolbar有滑动效果,必须做到如下三点:

注:CoordinatorLayout如果是最外的布局要去掉:

1、CoordinatorLayout必须作为整个布局的父布局容器。 2、 给需要滑动的组件设置 app:layout_scrollFlags=”scroll|enterAlways” 属性。 3、给你的可滑动的组件,也就是RecyclerView 或者 NestedScrollView 设置如下属性:

app:layout_behavior="@string/appbar_scrolling_view_behavior"

RecyclerView

RecyclerView使用介绍 base-adapter-helper的RecyclerView版

上下拉监听

SwipeRefreshLayout.OnRefreshListener 下拉监听

RecyclerView.OnScrollListener 到底监听

Android一点 RecyclerView上拉刷新

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    onListScrolled();
                }
            }
        });

RecyclerView多Item的情况

RecyclerView多Item的情况

其中 getItemViewType 用来返回当前项是哪种类型布局, getViewTypeCount 返回当前ListView总共多少种类型的布局

如果在 RecyclerView 实现多种Item,只需要实现一个 getItemType 方法,用来返回item的种类 
在 onCreateViewHolder 和 onBindViewHolder 方法中,第二个参数就是item的类型

Glide

Glide 系列预览


Github Android 开源库

GitHub Top 100的Android开源库


Other


疑问

  • XML布局是否可以像Jsp一样动态加载?

奇怪的错误:

由编译时出现的错误:

通过清理项目的缓存可解决。

第1个:

04-19 20:57:09.844 31614-31614/com.ms.meizinewsapplication E/AndroidRuntime: FATAL EXCEPTION: main
 Process: com.ms.meizinewsapplication, PID: 31614
 java.lang.NoSuchMethodError: No virtual method setMenuItemIconByCollect(Z)V in class Lcom/ms/meizinewsapplication/features/main/iview/DevWeekDetailIVew; or its super classes (declaration of 'com.ms.meizinewsapplication.features.main.iview.DevWeekDetailIVew' appears in /data/data/com.ms.meizinewsapplication/files/instant-run/dex/slice-slice_4-classes.dex)
	 at com.ms.meizinewsapplication.features.main.activity.DevWeekDetailActivity$2.onMenuItemClick(DevWeekDetailActivity.java:160)
	 at android.support.v7.widget.Toolbar$1.onMenuItemClick(Toolbar.java:169)
	 at android.support.v7.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:760)
	 at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:811)
	 at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
	 at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:958)
	 at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:948)
	 at android.support.v7.widget.ActionMenuView.invokeItem(ActionMenuView.java:618)
	 at android.support.v7.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:139)
	 at android.view.View.performClick(View.java:4908)
	 at android.view.View$PerformClick.run(View.java:20378)
	 at android.os.Handler.handleCallback(Handler.java:815)
	 at android.os.Handler.dispatchMessage(Handler.java:104)
	 at android.os.Looper.loop(Looper.java:194)
	 at android.app.ActivityThread.main(ActivityThread.java:5691)
	 at java.lang.reflect.Method.invoke(Native Method)
	 at java.lang.reflect.Method.invoke(Method.java:372)
	 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
	 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)

第2个:

04-19 20:13:37.194 5338-5416/com.ms.meizinewsapplication E/AndroidRuntime: FATAL EXCEPTION: RxCachedThreadScheduler-2
   Process: com.ms.meizinewsapplication, PID: 5338
   java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
	   at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
	   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
	   at java.util.concurrent.FutureTask.run(FutureTask.java:237)
	   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
	   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
	   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
	   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
	   at java.lang.Thread.run(Thread.java:818)
	Caused by: java.lang.NoSuchMethodError: No virtual method addCollectByUrl(Ljava/lang/String;Ljava/lang/String;)Z in class Lcom/ms/meizinewsapplication/features/base/utils/db/DbUtil; or its super classes (declaration of 'com.ms.meizinewsapplication.features.base.utils.db.DbUtil' appears in /data/data/com.ms.meizinewsapplication/files/instant-run/dex/slice-slice_9-classes.dex)
	   at com.ms.meizinewsapplication.features.base.model.CollectModel$1.call(CollectModel.java:44)
	   at com.ms.meizinewsapplication.features.base.model.CollectModel$1.call(CollectModel.java:39)
	   at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54)
	   at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:46)
	   at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:35)
	   at rx.Observable$2.call(Observable.java:162)
	   at rx.Observable$2.call(Observable.java:154)
	   at rx.Observable.unsafeSubscribe(Observable.java:8098)
	   at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)
	   at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
	   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
	   at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
	   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152) 
	   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 
	   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
	   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
	   at java.lang.Thread.run(Thread.java:818) 

app首次打开要很长时间 First launch take long time in Android Studio 2.0 & Gradle 2.0

app首次打开要很长时间 First launch take long time in Android Studio 2.0 & Gradle 2.0

所报日志:

04-27 10:24:16.241 12442-12450/com.ms.meizinewsapplication W/art: Suspending all threads took: 8.750ms
04-27 10:24:16.394 12442-12442/com.ms.meizinewsapplication W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
04-27 10:24:16.552 12442-12802/com.ms.meizinewsapplication D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true

                                                                             [ 04-27 10:24:16.554 12442:12442 D/         ]
                                                                             HostConnection::get() New Host Connection established 0xb4305d40, tid 12442
04-27 10:24:16.556 12442-12442/com.ms.meizinewsapplication D/Atlas: Validating map...

原因:

在2.0版本的新功能已添加即时运行。
要启用此功能的工具添加了大量的元信息,所以第一个构建和上传需要更多的时间。
请注意有关设置的minSdkVersion 15或更高,以获得任何盈利。

In version 2.0 a new feature was added instant-run.

To enable this feature tool adds a lots of meta information, so the first build and upload takes more time.

Be aware about setting minSdkVersion 15 or higher to get any profit.

解决步骤:

1、点击:Settings → Build, Execution, Deployment → Instant Run
2、取消选择:Enable Instant Run to hot swap code/resoure changes on deploy

这样会取消功能即时运行,但可以解决这个问题。

VerticalDrawerLayout 可以点击抽屉后面的控件

修改状态栏


增加分组的Adapter:BaseTypeItemQuickAdapter

主要还是BaseQuickAdapter为样本,重写getItemViewType,主要修改如下:

/**
 * 返回的布局判断
 * @param position
 * @return
 */
@Override
public int getItemViewType(int position) {

    if (position == 0 || oldCount == position) {
        return TYPE_TITLE;
    } else {
        return TYPE_ITEM;
    }

}

/**
 * 对不同类型的操作
 * @param viewGroup
 * @param viewType
 * @return
 */
@Override
public BaseAdapterHelper onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    View view = null;

    switch (viewType) {
        case TYPE_TITLE:

            view = LayoutInflater.from(viewGroup.getContext()).inflate(titleLayoutResId, viewGroup, false);

            break;
        case TYPE_ITEM:
            view = LayoutInflater.from(viewGroup.getContext()).inflate(itemLayoutResId, viewGroup, false);

            break;
    }

    if (view == null) {
        return null;
    }

    view.setOnClickListener(this);
    BaseAdapterHelper vh = new BaseAdapterHelper(view);
    return vh;
}
The MIT License (MIT) Copyright (c) 2016 qq137712630 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

有妹子的阅读app 展开 收起
Android
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Android
1
https://gitee.com/guidebird16312/MeiZiNews.git
git@gitee.com:guidebird16312/MeiZiNews.git
guidebird16312
MeiZiNews
MeiZiNews
master

搜索帮助