AutoNet (Android 網(wǎng)絡(luò)框架)

AutoNet (網(wǎng)絡(luò)框架)

AutoNet 代理了OkHttp滤灯, 處理了復(fù)雜繁瑣的網(wǎng)絡(luò)請求代碼巧娱! 使Android開發(fā)網(wǎng)絡(luò)應(yīng)用更加簡單赌躺,只需關(guān)注業(yè)務(wù)即可。

Git地址

1.Android版本:

Android版AutoNet

2.ios版本:

ios版AutoNet

AutoNet 技術(shù)交流群:

QQ: 141027175

Demo說明

  • app: AutoNet各個方式使用介紹
  • recommendeddemo: AutoNet推薦用法(注:Api使用了wanandroid的Api)

特色

  • 使用簡單徐勃、調(diào)用方便
  • 支持了同步事示、異步操作
  • 支持注解、 鏈?zhǔn)?/li>
  • 支持實體類僻肖、map傳值
  • 可防止內(nèi)存泄漏(需繼承RxFragmentActivity肖爵、或者RxFragment。并向AutoNet傳入相應(yīng)的生命周期)
  • 可動態(tài)添加和修改頭部
  • 可對請求參數(shù)數(shù)據(jù)進(jìn)行加密
  • 可自主處理返回的頭部數(shù)據(jù)
  • 可自主處理返回的body數(shù)據(jù)
  • 可自定義返回數(shù)據(jù)的類型
  • 可定義固定臀脏、靈活及臨時的域名劝堪、頭部信息(優(yōu)先級: 臨時>靈活>固定。 有效性: 固定 >= 靈活 > 臨時)
  • 支持網(wǎng)絡(luò)策略(網(wǎng)絡(luò)揉稚、本地秒啦、先本地后網(wǎng)絡(luò)、先網(wǎng)絡(luò)后本地)
  • 支持上傳文件和下載文件
  • 可直接獲得上游的Flowable, 用戶自己進(jìn)行操作結(jié)果搀玖。(eg: 使用zip去合并多個請求等)

gradle依賴

compile 'cn.xiaoxige:autonet-api:2.0.3'
annotationProcessor 'cn.xiaoxige:autonet-processor:2.0.3'

簡易使用demo

AutoNet_Android.png

使用

1. 初始化

1.1 AutoNetConfig(配置AutoNet的基本配置)注意:改配置基本是固定余境,如域名、頭部數(shù)據(jù)

  • 設(shè)置是否開啟Stetho調(diào)試配置
  • 設(shè)置默認(rèn)域名(key: default)
  • 設(shè)置多個域名
  • 設(shè)置頭部參數(shù)
  • 設(shè)置Okhttp的攔截器

1.2 AutoNet的初始化操作

AutoNet.getInstance().initAutoNet(Context, AutoNetConfig);
可以鏈?zhǔn)饺ピO(shè)置加密的回調(diào)巷怜,頭部數(shù)據(jù)的回調(diào)葛超,Body數(shù)據(jù)的回調(diào), eg:
AutoNet.getInstance().initAutoNet(Context, AutoNetConfig)
.setEncryptionCallback(new IAutoNetEncryptionCallback() {
        @Override
        public String encryption(Long key, String encryptionContent) {
            // 可通過key去加密參數(shù)
            return encryptionContent;
        }
    }).setHeadsCallback(new IAutoNetHeadCallBack() {
        @Override
        public void head(Object flag, Headers headers) {
            // 請求返回的頭部數(shù)據(jù)回調(diào)
        }
    }).setBodyCallback(new IAutoNetBodyCallBack() {
        @Override
        public boolean body(Object flag, String body) throw Exception {
            // 自己處理需要返回true
            return false;
        }
});
還可以再次設(shè)置域名和頭部數(shù)據(jù)(這里的配置為靈活的, 可在任意地方修改)
AutoNet.getInstance().updateOrInsertHead(key, value);
AutoNet.getInstance().updateOrInsertDomainNames(key, value);

2. 支持清單

2.1. 支持請求類型方式及策略

. 請求類型 請求方式 策略
注解方式 GET/POST/DELETE/PUT JSON/FORM/STREAM NET/LOCAL_NET/LOCAL/NET_LOCAL
鏈?zhǔn)酵?/td> GET/POST/DELETE/PUT JSON/FORM/STREAM NET/LOCAL
獲取上游發(fā)射器 GET/POST/DELETE/PUT JSON/FORM/STREAM NET/LOCAL
鏈?zhǔn)疆惒剑ㄍ扑]) GET/POST/DELETE/PUT JSON/FORM/STREAM NET/LOCAL_NET/LOCAL/NET_LOCAL

2.2. 支持的回調(diào)

. 注解方式 鏈?zhǔn)酵?/th> 獲取上游發(fā)射器 鏈?zhǔn)疆惒剑ㄍ扑])
IAutoNetBodyCallBack ? ? ? ?
IAutoNetHeadCallBack ? ? ? ?
IAutoNetEncryptionCallback ? ? ? ?
AbsAutoNetCallback ? ? ? ?
IAutoNetCallBack ? ? ? ?
IAutoNetComplete ? ? ? ?
IAutoNetDataBeforeCallBack ? ? ? ?
IAutoNetDataSuccessCallBack ? ? ? ?
IAutoNetDataCallBack ? ? ? ?
IAutoNetFileCallBack ? ? ? ?
IAutoNetLocalOptCallBack ? ? ? ?

3. 回調(diào)介紹

回調(diào)需要繼承實現(xiàn)AutoNet提供好的接口或者抽象類延塑。AutoNet已經(jīng)分類, 用戶需要什么功能就去集成相應(yīng)的接口或者抽象類即可

3.1 IAutoNetDataBeforeCallBack(數(shù)據(jù)返回前的處理答渔, 可定制要繼續(xù)返回給客戶前端的數(shù)據(jù))

public interface IAutoNetDataBeforeCallBack<T, Z> extends IAutoNetCallBack {
    // T為用戶指定的body要返回的實體類(AutoNet會自動轉(zhuǎn)換)关带, emitter為Rxjava的上游, 可改變其返回結(jié)果。 如果自己處理需要返回true宋雏。eg: T為一個實體類芜飘, 里面有一個List集合, 我們在View層只需要關(guān)注List集合磨总,則可以在這里直接重新定義并返回List集合嗦明, 并返回true。 (注意:其實這里還有一個功能就是蚪燕, 根據(jù)自己的需求去判斷是否集合為空更妙娶牌。emitter.onError(new EmptyError())。)
    boolean handlerBefore(T t, FlowableEmitter<Z> emitter);
}

3.2 IAutoNetDataSuccessCallBack(只關(guān)心成功的數(shù)據(jù)馆纳, 不關(guān)心失敗和數(shù)據(jù)為空的結(jié)果)

public interface IAutoNetDataSuccessCallBack<T> extends IAutoNetCallBack {
    // T為用戶需要返回的實體類
    void onSuccess(T entity);
}

3.3 IAutoNetDataCallBack(數(shù)據(jù)返回比較全的回調(diào), 包含了數(shù)據(jù)成功诗良、數(shù)據(jù)失敗、數(shù)據(jù)為空)

public interface IAutoNetDataCallBack<T> extends IAutoNetDataSuccessCallBack<T> {
    // 失敗
    void onFailed(Throwable throwable);
    // 數(shù)據(jù)為空(注意:如果不在IAutoNetDataBeforeCallBack去根據(jù)自己的業(yè)務(wù)去手動拋出emitter.onError(new EmptyError())的話鲁驶, AutoNet是不知道你的業(yè)務(wù)是什么的鉴裹, 所以在這個情況下AutoNet在body都為空的時候才調(diào)用onEmpty())
    void onEmpty();
}

3.4 IAutoNetLocalOptCallBack(需要用到本地操作, eg:網(wǎng)絡(luò)策略钥弯, 本地径荔、 先本地后網(wǎng)絡(luò), 先網(wǎng)絡(luò)后本地脆霎。 其實AutoNet并不能自動根據(jù)你的業(yè)務(wù)和字段給你建立數(shù)據(jù)庫猖凛, 需要自己去實現(xiàn))

public interface IAutoNetLocalOptCallBack<T> extends IAutoNetCallBack {
    T optLocalData(Map request) throws Exception;
}

3.5 IAutoNetFileCallBack(文件操作時的回調(diào), 需要關(guān)心上傳錯誤等需要繼承上面的IAutoNetDataCallBack)

public interface IAutoNetFileCallBack extends IAutoNetCallBack {
    // 上傳文件或者下載文件的進(jìn)度(0~100)
    void onPregress(float progress);
    // 上傳成功或者下載成功后的File文件回調(diào)
    void onComplete(File file);
}

3.6 IAutoNetComplete (請求結(jié)束后绪穆, 該回調(diào)會被調(diào)用辨泳,不管錯誤成功后都會調(diào)用)

public interface IAutoNetComplete extends IAutoNetCallBack {
    void onComplete();
}

3.7 AbsAutoNetCallback(數(shù)據(jù)回調(diào)的集合, 其實數(shù)據(jù)寫這個就行了玖院, 需要什么方法重寫什么方法即可)

// 其中 T為返回的body的實體類菠红,Z為自己處理后需要返回給View層后的實體類
public abstract class AbsAutoNetCallback<T, Z> implements IAutoNetDataBeforeCallBack<T, Z>, IAutoNetDataCallBack<Z>, IAutoNetComplete {

    @Override
    public boolean handlerBefore(T t, FlowableEmitter<Z> emitter) {
        return false;
    }

    @Override
    public void onSuccess(Z entity) {
    }

    @Override
    public void onFailed(Throwable throwable) {
    }

    @Override
    public void onEmpty() {
    }

    @Override
    public void onComplete() {
    }
}
}

4. 鏈?zhǔn)秸{(diào)用

AutoNet.getInstance().createNet()
    // 設(shè)置url后綴(除去域名)
    .setSuffixUrl(String)
    // 設(shè)置一個標(biāo)志, 會在全局的Head和Body中回調(diào)
    .setFlag(flag)
    // 參數(shù)
    .setParams(Map)
    .setParam(key, value)
    .setRequestEntity(IAutoNetRequest)
    // post請求(可傳參數(shù))
    .doPost(...)
    // get請求(可傳參數(shù))
    .doGet(...)
    // put(可傳參數(shù))
    .doPut(...)
    // delete(可傳參數(shù))
    .doDelete(...)
    // 指定使用的域名的Key(默認(rèn)default)
    .setDomainNameKey(String)
    // 設(shè)置網(wǎng)絡(luò)請求方式
    .setNetPattern(NetPattern)
    // 設(shè)置網(wǎng)絡(luò)策略
    .setNetStrategy(NetStrategy)
    // 設(shè)置請求類型(JSON/FORM/STREAM/OTHER)
    .setReqType(Type)
    // 設(shè)置返回類型(JSON/FORM/STREAM/OTHER)
    .setResType(Type)
    // 設(shè)置額外的參數(shù)(主要解決動態(tài)的拼在url中的參數(shù)难菌。eg: www.xxx.com/news/1, 最后的那個1為動態(tài))
    .setExtraDynamicParam(String)
    // 臨時的BaseUrl
    .setBaseUrl(String)
    // 鏈接超時時間
    .setConnectOutTime(Long)
    // 讀取時間
    .setReadOuTime(Long)
    // 寫入時間
    .setWriteOutTime(Long)
    // 需要加密的參數(shù)的key试溯, 可根據(jù)key去加密其中類型的參數(shù), 在初始化時使用到了郊酒,還記得嗎(上去看看)
    .setEncryptionKey(Long)
    // 設(shè)置MediaType
    .setMediaType(String)
    // 發(fā)送文件
    .setPullFileParams()
    // 接受文件
    .setPushFileParams()
    // 設(shè)置臨時頭部
    .setHeads(String[])
    // 綁定生命周期遇绞,防止內(nèi)存泄漏(忘了?上面有說)
    .setTransformer(...)
    // 數(shù)據(jù)回調(diào)(2章節(jié)中講到的一些回調(diào))
    (1).start(CallBack);
    // 獲得上游燎窘, 用戶自己處理結(jié)果
    (2).getFlowable(Class);
    // 同步請求
    (3).synchronizationNet(Class)

5. 獲取上游并處理(已zip合并為例摹闽, 這里只是用了兩個, 其實RxJava提供了好多褐健, 當(dāng)然還有其他用法付鹿,詳情可以看RxJava的用法)

// zip
// 1. 得到wanAndroid的上游發(fā)射器
Flowable wanAndroidFlowable = getWanAndroidFlowable();
// 2. 得到百度的上游發(fā)射器
Flowable baiduFlowable = getBaiduFlowable();
// 3. 合并
//noinspection unchecked
Flowable.zip(wanAndroidFlowable, baiduFlowable, new BiFunction<WanAndroidResponse, String, ZipEntity>() {
    @Override
    public ZipEntity apply(WanAndroidResponse wanAndroidResponse, String s) throws Exception {
        ZipEntity zipEntity = new ZipEntity();
        List<WanAndroidEntity> data = wanAndroidResponse.getData();
        zipEntity.setData(data);
        zipEntity.setBaidu(s);
        return zipEntity;
    }
}).subscribe(new Subscriber<ZipEntity>() {
    @Override
    public void onSubscribe(Subscription subscription) {
        subscription.request(Integer.MAX_VALUE);
    }

    @Override
    public void onNext(ZipEntity o) {
        List<WanAndroidEntity> data = o.getData();
        // 這里進(jìn)行模擬, 如果 wanAndroid 數(shù)據(jù)是必須的數(shù)據(jù), 為空就是錯誤
        if (data == null || data.isEmpty()) {
            Toast.makeText(MainActivity.this, "數(shù)據(jù)為空了", Toast.LENGTH_SHORT).show();
            return;
        }

        Toast.makeText(MainActivity.this, "成功:\n" + o.toString(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onError(Throwable throwable) {
        if (throwable instanceof EmptyError) {
            Toast.makeText(MainActivity.this, "數(shù)據(jù)為空了", Toast.LENGTH_SHORT).show();
            return;
        }
        Toast.makeText(MainActivity.this, "數(shù)據(jù)錯誤:\n" + throwable.getMessage(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onComplete() {
        Toast.makeText(MainActivity.this, "結(jié)束", Toast.LENGTH_SHORT).show();
    }
});


private Flowable getWanAndroidFlowable() {
    return AutoNet.getInstance().createNet()
            .setDomainNameKey("wanandroid")
            .setSuffixUrl("/wxarticle/chapters/json")
            .doGet()
            // 設(shè)置追蹤舵匾, 為了在body攔截中俊抵, 不讓其他邏輯進(jìn)行了攔截
            .setFlag(666)
            .getFlowable(WanAndroidResponse.class)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io());
}

private Flowable getBaiduFlowable() {
    return AutoNet.getInstance().createNet()
            // 設(shè)置追蹤, 為了在body攔截中坐梯, 不讓其他邏輯進(jìn)行了攔截
            .setFlag(666)
            .getFlowable(String.class)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io());
}

6. 注解方式

6.1 注解介紹

  • AutoNetAnontation 網(wǎng)絡(luò)參數(shù)設(shè)置(value(除去域名)徽诲、flag、 writeTime吵血、readTime谎替、connectOutTime)
  • AutoNetBaseUrlKeyAnontation BaseUrl的選擇標(biāo)識key(value)
  • AutoNetDisposableBaseUrlAnontation 本次請求臨時使用的BaseUrl(value)
  • AutoNetDisposableHeadAnnontation 本次請求臨時使用的頭部信息(value[])
  • AutoNetEncryptionAnontation 加密參數(shù)設(shè)置(key, value)
  • AutoNetMediaTypeAnontation 請求的MediaType(value)
  • AutoNetPatternAnontation 請求方式(value(get/post/put/delete))
  • AutoNetStrategyAnontation 網(wǎng)絡(luò)請求策略(value(net/local/local_net/net_local))
  • AutoNetTypeAnontation 請求和返回的請求類型(reqType(json/form/stream), resType(json/form/stream))

6.2 代理類名規(guī)則

如果是回調(diào)是內(nèi)部 則代理類名為 外層類名 + 回調(diào)類名 + AutoProxy
如果回調(diào)就是一個類 則代理類名為 回調(diào)類名 + AutoProxy

6.3 注意

如果使用的是注解方式請求網(wǎng)絡(luò), 在寫完類后践瓷,請build -> rebuild project院喜。

6.4 例子

一、普通請求

@AutoNetPatternAnontation(AutoNetPatternAnontation.NetPattern.GET)
@AutoNetAnontation("/init.php")
@AutoNetBaseUrlKeyAnontation("jsonTestBaseUrl")
public class doGet implements IAutoNetDataBeforeCallBack<TestResponseEntity>, IAutoNetDataCallBack<List<Entity>> {
    @Override
    public boolean handlerBefore(TestResponseEntity o, FlowableEmitter emitter) {
        List<Entity> entitys = o.getList();
        if(entitys == null || entitys.isEmpty()){
            emitter.onError(new EmptyError());
            return true;
        }
        emitter.onNext(entitys);
        return true;
    }

    @Override
    public void onSuccess(List<Entity> entitys) {

    }

    @Override
    public void onFailed(Throwable throwable) {

    }

    @Override
    public void onEmpty() {
    }
}

先build下晕翠, 然后再需要發(fā)送該網(wǎng)絡(luò)連接時:
MainActivitydoGetAutoProxy.startNet(MainActivity.this喷舀, bindUntilEvent(ActivityEvent.DESTROY));
注意:MainActivitydoGetAutoProxy這個類生成的規(guī)則前面已給出

二、 上傳文件

@AutoNetBaseUrlKeyAnontation("upFile")
@AutoNetTypeAnontation(reqType = AutoNetTypeAnontation.Type.STREAM)
@AutoNetPatternAnontation(AutoNetPatternAnontation.NetPattern.POST)
public class PushFile implements IAutoNetDataCallBack, IAutoNetFileCallBack {

    @Override
    public void onFailed(Throwable throwable) {
    }

    @Override
    public void onEmpty() {
    }

    @Override
    public void onSuccess(Object entity) {
    }

    @Override
    public void onPregress(float progress) {
    }

    @Override
    public void onComplete(File file) {
    }
}

請求方式:
MainActivityPushFileAutoProxy.pushFile(MainActivity.this, "upload", path + File.separator + "a.png");

三淋肾、 下載文件

@AutoNetBaseUrlKeyAnontation("downFile")
@AutoNetTypeAnontation(resType = AutoNetTypeAnontation.Type.STREAM)
@AutoNetAnontation("/apk/downLoad/android_4.2.4.apk")
public class PullFile implements IAutoNetDataCallBack<File>, IAutoNetFileCallBack {
    @Override
    public void onFailed(Throwable throwable) {
    }

    @Override
    public void onEmpty() {
    }

    @Override
    public void onSuccess(File entity) {
    }

    @Override
    public void onPregress(float progress) {
    }

    @Override
    public void onComplete(File file) {
    }
}

請求方式:
MainActivityPullFileAutoProxy.pullFile(MainActivity.this, path, "pppig.apk");

7. 簡單的例子

初始化

AutoNetConfig config = new AutoNetConfig.Builder()
            .isOpenStetho(BuildConfig.DEBUG)
            .setDefaultDomainName(ApiConstant.BASE_POST_URL)
            .build();

AutoNet.getInstance().initAutoNet(this, config).setBodyCallback(new IAutoNetBodyCallBack() {
        @Override
        public boolean body(Object flag, String body) {
            // 全局的硫麻, 所有的請求都會到這里
            // 在這里可以根據(jù)自己的統(tǒng)一的字段去判斷code什么的是否成功了
            // 如果不成功可以以異常出去, 最后會在onFailed回調(diào)
            if (!TextUtils.isEmpty(body)) {
                try {
                    BaseResponse baseResponse = new Gson().fromJson(body, BaseResponse.class);
                    if (!baseResponse.isSuccess()) {
                        throw new CustomError(baseResponse.getMessage());
                        return true;
                    }
                } catch (Exception e) {
                    emitter.onError(e);
                    return true;
                }
            }
            return false;
        }
    });

簡單使用

AutoNet.getInstance().createNet()
    .setSuffixUrl("/test")
    .setParam("a", "a")
    .setParam("b", 1)
    .doPost()
    .start(new TestListCallback());
private class TestListCallback extends AbsAutoNetCallback<TestListResponse, List<TestEntity>> {

    @Override
    public boolean handlerBefore(TestListResponse response, FlowableEmitter emitter) {
        // 這里可以在數(shù)據(jù)返回以前樊卓, 再次指定要返回的數(shù)據(jù)拿愧, 并根據(jù)自己的業(yè)務(wù)去判斷是否為空(注意這里是在分線程中)
        List<TestEntity> entitys = response.getData();
        if (entitys == null || entitys.isEmpty()) {
            emitter.onError(new EmptyError());
            return true;
        }
        //noinspection unchecked
        emitter.onNext(entitys);
        return true;
    }

    @Override
    public void onSuccess(List<TestEntity> entitys) {
        bindUserInfo(entitys);
        mEmptyLayout.showContent();
        refreshLayout.refreshComplete();
    }

    @Override
    public void onFailed(Throwable throwable) {
        HandlerError.handlerError(throwable);
        mEmptyLayout.showContent();
        refreshLayout.refreshComplete();
    }

    @Override
    public void onEmpty() {
        HandlerError.handlerEmpty();
        mEmptyLayout.showContent();
        refreshLayout.refreshComplete();
    }
}

2.0.+ 修改點(該版本修改較大, 架構(gòu)等都有修改碌尔, 所以和之前的版本可能有個別用法不同骡显,如果切換最新版本需要主要一下幾點)

一蔫仙、 支持了同步請求,異步請求

  • 增添了synchronizationNet(Class)方法。 Class 即后臺返回的數(shù)據(jù)結(jié)構(gòu)類型调衰。
  • 修改了getFlowable(Class), 增加參數(shù)Class碴倾。Class 即后臺返回的數(shù)據(jù)結(jié)構(gòu)類型检碗。

二扇雕、 body回調(diào)

  • 去除 FlowableEmitter 參數(shù), 在之前需要進(jìn)行特出處理的比如 emitter.onError(new Custom("...")) 改為 throw new Custom("...")

三募书、 增加了IAutoNetComplete 接口绪囱, 如果你想監(jiān)聽請求結(jié)束, 就集成IAutoNetComplete莹捡。 它不管是否成功失敗最后都會回調(diào)

四鬼吵、 如果是下載文件操作, 那么請求返回的ResponseClass 需要制定為 File.class類型

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末道盏,一起剝皮案震驚了整個濱河市而柑,隨后出現(xiàn)的幾起案子文捶,更是在濱河造成了極大的恐慌荷逞,老刑警劉巖媒咳,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異种远,居然都是意外死亡涩澡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門坠敷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妙同,“玉大人,你說我怎么就攤上這事膝迎≈嘀悖” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵限次,是天一觀的道長芒涡。 經(jīng)常有香客問我,道長卖漫,這世上最難降的妖魔是什么费尽? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮羊始,結(jié)果婚禮上旱幼,老公的妹妹穿的比我還像新娘。我一直安慰自己突委,他們只是感情好柏卤,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著匀油,像睡著了一般缘缚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钧唐,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天忙灼,我揣著相機與錄音,去河邊找鬼钝侠。 笑死该园,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的帅韧。 我是一名探鬼主播里初,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼忽舟!你這毒婦竟也來了双妨?” 一聲冷哼從身側(cè)響起淮阐,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刁品,沒想到半個月后泣特,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡挑随,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年状您,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兜挨。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡膏孟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拌汇,到底是詐尸還是另有隱情柒桑,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布噪舀,位于F島的核電站魁淳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏傅联。R本人自食惡果不足惜先改,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蒸走。 院中可真熱鬧仇奶,春花似錦、人聲如沸比驻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽别惦。三九已至狈茉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掸掸,已是汗流浹背氯庆。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扰付,地道東北人堤撵。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像羽莺,于是被迫代替她去往敵國和親实昨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,810評論 6 342
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,115評論 25 707
  • 籍雨亭6月11日感恩日記 1盐固、感恩北京這幾天的天氣荒给,很涼快丈挟,謝謝、謝謝志电、謝謝 2曙咽、感恩淘寶這個好平臺,買了好多出行...
    籍雨亭閱讀 214評論 0 0
  • 有可能你會問:“你在新年買年貨了沒溪北?包餃子了沒桐绒?大掃除了沒?貼對聯(lián)了沒?” “沒有! 我把那些...
    和薇閱讀 246評論 0 1
  • 最近看了篇文章《中國詩詞大會沒做到的夺脾,王者榮耀做到了》之拨。 大概意思是說,玩兒了王者榮耀之后的諸多玩家咧叭,開始更多的了...
    離子凝膠閱讀 2,760評論 0 1