Toutiaoプロジェクトのソースコードの読み取り

プロジェクトアドレス
サードパーティのToutiaoクライアント、MVP + RxJava + Retrofit

建築

標準MVPアーキテクチャ

IBasePresenter

各Pレイヤーには、更新インターフェイスと表示ネットワークエラー要件があります

public interface IBasePresenter {
    
    
    void doRefresh();
    void doShowNetError();
}
IBaseView

各V層を持っているとのインタフェースの表示ステータスページ、設定Presenter、およびRxJavaメモリリークを防ぐために、配信停止を。

public interface IBaseView<T> {
    
    
    void onShowLoading();
    void onHideLoading();
    void onShowNetError();
    void setPresenter(T presenter); // P类型由V层泛型决定
    <X> AutoDisposeConverter<X> bindAutoDispose();
}
ニュースページ構造の分析

新しいINewsArticleインターフェースを作成しますINewsArticle.ViewインターフェースはによってNewsArticleView実装さINewsArticle.Presenterれ、によってNewsArticlePresenter実装さます。

public interface INewsArticle {
    
    
    // INewsArticle.View接口继承自IBaseListView接口,可以看作是对IBaseListView接口方法的补充.
    // INewsArticle.View接口中定义了新闻页的行为方法
    // IBaseListView<Presenter> 该泛型决定了P层类型,也就是该P层类型必须为INewsArticle.Presenter类型.
    interface View extends IBaseListView<Presenter> {
    
    
        void onLoadData();
        void onRefresh();
    }
    // INewsArticle.Presenter接口继承自IBasePresenter接口,可以看作是对IBaseListView接口方法的扩充
    // INewsArticle.Presenter接口中定义了新闻页P层的行为方法
    interface Presenter extends IBasePresenter {
    
    
        void doLoadData(String... category);
        void doLoadMoreData();
        void doSetAdapter(List<MultiNewsArticleDataBean> dataBeen);
        void doShowNoMore();
    }
}
ニュースページの分析
  1. NewsArticlePresenter
public class NewsArticlePresenter implements INewsArticle.Presenter {
    
    
    private INewsArticle.View view;// NewsArticleView层引用, 用来更新UI.
    public NewsArticlePresenter(INewsArticle.View view) {
    
    
            this.view = view;
    }
}
  1. NewsArticleView
// <INewsArticle.Presenter>: 该泛型是用来确定创建得P层对象的类型.
public class NewsArticleView extends BaseListFragment<INewsArticle.Presenter> implements INewsArticle.View {
    
    
    // IBaseView接口中定义得setPresenter()方法,在这里实现.
    @Override
    public void setPresenter(INewsArticle.Presenter presenter) {
    
    
        if (null == presenter) {
    
    
            // this.presenter: 在BaseFragment中定义了一个变量presenter,专门用来接收P层对象..
            this.presenter = new NewsArticlePresenter(this);
        }
    }
}
MVPアーキテクチャの概要
// 顶层接口定义一些共有的方法
interface IBaseP {
    
    
}

interface IBaseV<T> {
    
    
    // 为V层创建P层对象
    // 泛型T确定了P层对象的类型
    T setPresenter(T t);
}

// 次级接口定义自己特有的方法
interface IMy {
    
    
    // <MyP>: 确定P层对象的类型为MyP
    interface MyV extends IBaseV<MyP> {
    
    
        void refreshPage();// 更新UI
    }

    interface MyP extends IBaseP {
    
    
        void getData();// 获取数据
    }
}
// P层的实现
// <T extends IMy.MyV>: 确定P层持有的V层类型
class MyPresenter<T extends IMy.MyV> implements IMy.MyP {
    
    
    T mView;

    public MyPresenter(T mView) {
    
    
        this.mView = mView;
    }

    @Override
    public void getData() {
    
    
        System.out.println("获取数据");
        mView.refreshPage();// 获取数据之后更新界面
    }
}
// 定义BaseActivity,<T>用来确定P层对象的类型.
abstract class BaseActivity<T> implements IBaseV<T> {
    
    
    T mPresenter;

    public BaseActivity() {
    
    
        // 调用子类实现的setPresenter()方法,创建P层对象,由父类mPresenter变量保存.
        mPresenter = setPresenter(mPresenter);
    }
}
// V层实现类
// <IMy.MyP>: 确定P层对象类型.
class MyActivity extends BaseActivity<IMy.MyP> implements IMy.MyV {
    
    
    public MyActivity() {
    
    
        mPresenter.getData();
    }

    @Override
    public void refreshPage() {
    
    
        System.out.println("更新界面");
    }
    // IBaseV.setPresenter()接口方法的具体实现.
    @Override
    public IMy.MyP setPresenter(IMy.MyP myP) {
    
    
        // <IMy.MyV>: 用来确认P层中V对象的类型.
        return new MyPresenter<IMy.MyV>(this);
    }
}
public class MVP {
    
    
    public static void main(String[] args) {
    
    
        // 模拟Activity启动之后获取数据然后刷新界面
        new MyActivity();
    }
}

インターネット

ネットワークフレームワークはRetorfit + OkHttp + RxJavaを使用します

Cookie管理

サードパーティのライブラリが使用されます。簡単な設定は次のとおりです。PersistentCookieJar

ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(InitApp.AppContext));
OkHttpClient client = new OkHttpClient.Builder()
        .cookieJar(cookieJar)
        .cache(cache)
        .connectTimeout(10, TimeUnit.SECONDS)
        .readTimeout(15, TimeUnit.SECONDS)
        .writeTimeout(15, TimeUnit.SECONDS)
        .retryOnConnectionFailure(true)
        .build();
キャッシュ管理

OkHttpキャッシュにはRxCacheを使用することをお勧めします。これは非常に使いやすいです。

RxJavaメモリリークへの対処

プロジェクトは使用されていませんRxLifecycle使用していAutoDisposeます。
例:

 RetrofitFactory.getRetrofit().create(IMobileNewsApi.class)
         .getNewsComment(groupId, offset)
         .subscribeOn(Schedulers.io())
         ...
         .observeOn(AndroidSchedulers.mainThread())
         .as(view.bindAutoDispose()) // bindAutoDispose该方法由View层实现.
         .subscribe(list -> {
    
    
             if (null != list && list.size() > 0) {
    
    
                 doSetAdapter(list);
             } else {
    
    
                 doShowNoMore();
             }
         }, throwable -> {
    
    
             doShowNetError();
             ErrorAction.print(throwable);
         });

Viewレイヤーの実装方法bindAutoDispose()

public abstract class BaseFragment<T extends IBasePresenter> extends Fragment implements IBaseView<T> {
    
    
    /**
     * 绑定生命周期
     */
    @Override
    public <X> AutoDisposeConverter<X> bindAutoDispose() {
    
    
        return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider
                .from(this, Lifecycle.Event.ON_DESTROY)); // 当Activity被销毁时候,接触RxJava间的订阅.
    }
}

ハイライト効果

TapTargetViewこのライブラリがMainActivity.showTapTarget()使用され、プロジェクトのメソッドで使用さます。

APPプロパティを動的に設定する

プロジェクトのSettingUtilツールは、テーマの色、ナビゲーションバーの色、ビデオの水平画面、フォントサイズなどを設定できます。

manifestActivity配置

<activity
    android:name=".MainActivity"
    android:configChanges="orientation|screenSize|uiMode"
    android:label="@string/app_name"
    android:theme="@style/AppTheme.NoActionBar"/>

Androidデバイスの実行中、水平および垂直の画面切り替え、キーボードなどのデバイス構成が変更され、アクティビティが再起動する場合があります。破棄する前に、onSaveInstanceState()を呼び出して、使用するデータをアプリケーションに保存します。アクティビティが復元されたとき。電話が必要なandroid:configChanges場合構成を変更してもアクティビティが再開されない場合は、現在のアクティビティにいくつかのプロパティ追加する必要があります。これにより、構成が変更されたときにアクティビティは再開されませんが、アクティビティonConfigurationChanged()メソッドは再開されます。と呼ばれます。

  • navigation:ナビゲーションバーが変更されました
  • fontScale:フォントが変更されました
  • uiMode:ユーザーモードが変更されました
  • orientation:画面の向きが変わりました
  • screenSize:画面サイズが変更されました
  • keyboardHidden:キーボードの使いやすさが変更されました

おすすめ

転載: blog.csdn.net/MoLiao2046/article/details/106957752
おすすめ