Giter Club home page Giter Club logo

minimalistweather's Introduction

MinimalistWeather

欢迎关注微信公众号:BaronTalk

一. 前言

推荐阅读:

MinimalistWeather 是 Android 平台上一款开源天气 App ,目前还在开发中。项目基于 MVP 架构,采用各主流开源库实现。开发此项目主要是为展示各种开源库的使用方式以及 Android 项目的设计方案,并作为团队项目开发规范的一部分。

采用的开源库包括:

  • RxJava
  • Retrofit2
  • OKHttp3
  • ORMLite
  • Dagger2
  • ButterKnife
  • RetroLambda
  • Stetho

本项目还展示了:

  • MVP+RxJava在实际项目中的应用,MVP中RxJava生命周期的管理...;
  • 上述罗列的各种开源框架的使用方法;
  • Java8 Lambda表达式和Stream API的用法;
  • 怎样适配Material Design;
  • ToolBar、RecycleView、CardView、CoordinatorLayout等新控件的用法;
  • Gradle的基本配置(包括签名打包、项目依赖等等);
  • 如何更好的管理Gradle依赖库的版本;
  • 代码混淆配置;
  • 如何快速开发一款结构清晰、可扩展性强的Android Application。

二. 项目结构设计图

架构设计图

三. 项目包结构介绍

App Module包结构

-com.baronzhang.android.weather
    + base	  // MVP 各组件的基类及相关基础类
    + data    // MVP 中所有 Model 层的数据处理都在这里
    - feature       // 业务 feature,feature 内按页面划分,如果是大型项目可以按业务模块划分,对于特大型项目建议走模块化(组件化)方案,每个业务模块再按照 MinimalistWeather 的分包规则来分包
        + home
        - selectcity
            - xxActivity.java // Activity 作为全局的控制者,用来负责创建 View 和 Presenter 的实例
            - xxFragment.java 
            - xxPresenter.java
            - xxContract.java // 契约类,用来统一管理 View 和 Presenter 的接口
    + util
    - AppConstants.java        // App 全局常量
    - WeatherApplication.java  // Application 类
    - WelcomeActivity.java     // 放在这里是为了便于查找应用程序入口

欢迎扫码关注公众号交流

三. 开源许可 Hex.pm

Copyright 2017 Baron Zhang

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

minimalistweather's People

Contributors

baronz88 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

minimalistweather's Issues

项目构建不下来

grade版本和sdk位置都没错,卡住了,不会是网卡吧?我是download下来的

DrawerMenuPresenter未用Dagger注入

你好,我发现楼主要用dagger进行对mainActivity注入时,对HomePagePresenter用了dagger2注入,而DrawerMenuPresenter却并未用dagger注入,却还留头DrawerMenuModule,但我加了DrawerMenuComponent后,却又编译不过。希望楼主对DrawerMenuPresenter也进行Dagger注入。

关于分包的问题

假如把 BaseActivity写在library的话,那么在BaseActivity访问不到app里的东西,比如 App.getInstance().removeActivity(this);这种一些初始化的操作没法在BaseActivity进行。
请问怎么解决这个问题?
我想了一个办法是在app包里再建一个AppBaseActivity继承BaseActivity去实现,但是觉得不太好,请问下还有更好的实现方式吗?

第三方库太多

看你们的安居客app就使用了非常多的框架,里面有很多冗余的东西,连依赖注入框架就使用两个一样的

Dagger2

感觉Dagger2用的太少了,MVP的父类可以注入,网络层也可注入,fastjson什么的都可以以bean的形式分装,然后注入

天气api指示不准

实测今天上海天气轻度污染,但指示却指向良,颜色值正确。
另外,直辖市下的区无法选择天气。

HomePageFragment的forecastRecyclerView.setItemAnimator

在HomePageFragment的119行写的是
forecastRecyclerView.setItemAnimator(new DefaultItemAnimator());
应该是
detailRecyclerView.setItemAnimator(new DefaultItemAnimator());
因为这部分一直在说detailRecyclerView,而且在下面友设置了一遍
forecastRecyclerView.setItemAnimator(new DefaultItemAnimator());

单元测试的问题

您好,在您的这个项目中好像并没有看到单元测试部分的代码。。
因为google 的todo mvp这个开源项目,里面很重要的一环就是对m层,p层等分别做了单元测试。
感觉单测还是挺重要的。

Activity的注入问题

你好.
你项目中在Activity使用Dagger的方式和我之前很像,但我发现了这个类过多的问题.
一个Activity就需要一个Component和Module.如果项目Activity很多的话,很导致类非常多.
我后来将所有的Activity中的注入都放到一个Component和Module里面去配置.不过这个也有个问题,我项目中Presenter里面的,V层即Activity,都是通过Module中的@Provides去提供注入的,而Dagger会检查空值问题,最后只能在对象上标注@Nullable,才能编译通过.而且这也导致了很多空指针警告.不知道你在项目中有没有遇到这个问题呢?
ActivityModule.java

    @Nullable
    @Provides
    SplashContract.View providesSplashView() {
        return mSplashView;
    }

    @Nullable
    @Provides
    MainContract.View providesMainView() {
        return mMainView;
    }

    @Nullable
    @Provides
    UserListContract.View providesUserListView() {
        return mUserListView;
    }
   ....

ActivityComponent.java

@ActivityScoped
@Component(dependencies = DataRepositoryComponent.class,modules = ActivityModule.class)
public interface ActivityComponent {

    void inject(SplashActivity activity);

    void inject(MainActivity activity);

    void inject(UserListActivity activity);
    ...
}

需要注入的Presenter.java

    private SplashContract.View mView;
    private LocallyData mLocallyData;
    //只能通过@SuppressWarnings("ConstantConditions")去忽略空指针警告
    @Inject
    SplashPresenter(@Nullable SplashContract.View view, LocallyData locallData) {
        mView = view;
        mLocallyData = locallData;
    }

onResume中mPresenter.subscribe()报空指针异常

我在线上的产品中使用了项目中推荐的mvp模式,(不过并没有使用Dragger注入的方式关联Fragment与Presenter)
如下
1.Activity中Fragment与Presenter的初始化
CartFragment cartFragment = new CartFragment();
CartPresenter cartPresenter = new CartPresenter(this, cartFragment);
cartFragment.setPresenter(cartPresenter);

问题所在
有如下代码
@OverRide
public void onResume() {
super.onResume();
mPresenter.subscribe();
}

然后在腾讯bugly中统计的异常信息中有统计到了如下的错误

java.lang.NullPointerException:Attempt to invoke interface method 'void 包名.contract.CartContract$Presenter.subscribe()' on a null object reference
6 包名.view.fragment.CartFragment.onResume
这是因为生命周期的问题导致Fragment中的presenter为空导致的吗?
如果只是否可以在如下两个方法房中保存/恢复 presenter变量以解决这个问题
@OverRide
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}

@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
    super.onViewStateRestored(savedInstanceState);
}

对于Presenter层持有的View如何更好的控制View报空的问题

在框架实践使用中,发现Presenter层持有的View实例会出现报空问题,在开发过程中如何可以很好控制View空的问题,现在的解决方案是每次使用View都进行判空处理,感觉过于笨拙,有没有好的解决方案可以很好的处理这个问题,向大牛请教!😁

关于合同类中关于接口ContractView的设计请教

合同类中接口View的抽象方法的设计
是应该以一个逻辑为一个抽象方法呢,
还是应该以对一个控件的调用为一个抽象方法呢?
比如有一个逻辑是给TextView设置的文本为空字符时,则隐藏改TextView

方式一
class View extends Fragment implements Contract.View{

  void displayMsg(Strint text){
       if(TextUtil.isEmpty(text)){
           mTextView.setVisibility(View.GONE);
           retrun;
      }
      mTextView.setVisibility(View.VISIBLE);
      mTextView.setTextView(text);
 }

}
方式二.
class View extends Fragment implements Contract.View{

  void displayMsg(Strint text){
      mTextView.setTextView(text);
 }

  void hideTextView(){
       mTextView.setVisibility(View.GONE);
 }
  
 void showTextView(){
      mTextView.setVisibility(View.VISIBLE);
 }

}

RxJava在crash时,堆栈信息不详细的问题

哥们看你写的文章应该 使用RxJava好几年了, 项目中的线上crash, 如果是Rxjava内引起的,那么crash日志可能并不能把详细的堆栈信息抓到, 这个问题你是怎么 解决的, 如果项目比较小可能问题不大,如果是 较大型的项目,比如代码量在50w以上,遇到过吗?

请问?

请问下,为什么获取不到城市的天气信息了?返回都是null

RxJava在crash时,堆栈信息不详细的问题

哥们看你写的文章应该 使用RxJava好几年了, 项目中的线上crash, 如果是Rxjava内引起的,那么crash日志可能并不能把详细的堆栈信息抓到, 这个问题你是怎么 解决的, 如果项目比较小可能问题不大,如果是 较大型的项目,比如代码量在50w以上,遇到过吗?

数据加载不出来

磊哥,天气预报相关的数据好像加载不出来,不知道是不是接口出问题了?

Presenter报空指针异常

当应用退出到后台,由于内存不足kill掉次应用,此时回到应用Presenter就会包空指针异常

编译报错

AGPBI: {"kind":"error","text":"error: expected enum but got (raw string) auto.","sources":[{"file":"C:\Users\freeman\.gradle\caches\transforms-1\files-1.1\material-1.0.0-rc01.aar\75017e670a4f9177575cc0f217a79703\res\values\values.xml","position":{"startLine":965,"startColumn":4,"startOffset":66972,"endLine":972,"endColumn":10,"endOffset":67488}}],"original":"","tool":"AAPT"}
AGPBI: {"kind":"error","text":"error: expected reference but got (raw string) #000000.","sources":[{"file":"D:\android-project\MinimalistWeather\app\build\intermediates\incremental\mergeDebugResources\merged.dir\values\values.xml","position":{"startLine":3279}}],"original":"","tool":"AAPT"}
:app:processDebugResources
编译过程报这个错误

不错的感觉

clone下来看看,你的mvp 和Google官方的todo mvp 好像

未选择城数据默认加载数据为空,会报错

Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void com.baronzhang.android.weather.contract.DrawerContract$Presenter.subscribe()' on a null object reference
at com.baronzhang.android.weather.view.fragment.DrawerMenuFragment.onCreateView(DrawerMenuFragment.java:120)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2239)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1332)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1574)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1641)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2959)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:550)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1249)
at android.app.Activity.performStart(Activity.java:6762)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2651)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2749) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1498) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:160) 
at android.app.ActivityThread.main(ActivityThread.java:6200) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:874) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:764) 

关于城市管理页面的一点疑问

CityManagerFragment中列表项的点击事件响应直接使用了PreferenceHelper;
即View直接调用了Model层不知道是不是有点不妥。代码如下
cityManagerAdapter.setOnItemClickListener(new CityManagerAdapter.OnCityManagerItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            try {
                PreferenceHelper.savePreference(WeatherSettings.SETTINGS_CURRENT_CITY_ID, weatherList.get(position).getCityId() + "");
                CityManagerFragment.this.getActivity().finish();
            } catch (InvalidClassException e) {
                e.printStackTrace();
            }
        }

}

关于断言assert

在ApiConfiguration类中,您使用了断言,在安卓中推不推荐使用断言呢?

关于Okhttp3.6.0严格模式初始化时机

你好,OKhttp版本3.6.0初始化时加入了读操作,Application在oncreate时调用init方法,严格模式下会警告,请问有init方法有没有什么更好的调用时机呢?谢谢!

java 8编译问题

我现在用的as2.3, 使用java8来编译会提示要求开启jack,我看您老的项目里没有设置这个,引用了
'me.tatarka.retrolambda' 插件, 请问这个的作用是 ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.