(七)安卓框架搭建之其他必備要素的封裝或引入

1.安卓6.0權(quán)限處理機(jī)制绣溜、android 7.0讀寫(xiě)

M的權(quán)限慷彤、N外部文件讀寫(xiě),相信坑了不少同學(xué)怖喻〉谆框架里必須得有!

1.1權(quán)限問(wèn)題

權(quán)限問(wèn)題之前看到的一個(gè)很好的封裝方法锚沸,真正做到一個(gè)方法解決問(wèn)題跋选,而且我試驗(yàn)下來(lái),確實(shí)很完美哗蜈。

依賴(lài):

compile 'pub.devrel:easypermissions:0.1.9'

封裝:

在第三方基礎(chǔ)上前标,重新封裝,新建
EasyPermission距潘、PermissionCallBackM炼列、PermissionUtils。因?yàn)槠鶈?wèn)題音比,而且這部分代碼并不是我本人寫(xiě)的俭尖,就不貼出來(lái)了,小伙伴可以到源碼中查看洞翩。下面重點(diǎn)看一下在BaseActivity里的封裝:

package com.example.burro.demo.appframework.ui;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.example.burro.demo.appframework.BaseApplication;
import com.example.burro.demo.appframework.mvp.presenter.BasePresenter;
import com.example.burro.demo.appframework.mvp.view.BaseView;
import com.example.burro.demo.appframework.permission.EasyPermission;
import com.example.burro.demo.appframework.permission.PermissionCallBackM;
import com.example.burro.demo.appframework.permission.PermissionUtils;
import com.example.burro.demo.appframework.util.ToastUtils;
import com.example.burro.demo.dataframework.model.BaseResultBean;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * BaseActivity Activity基類(lèi)
 * butterKnife的綁定 初始方法的設(shè)定 presentet和view的綁定
 * Created by burro on 2017/9/23.
 */
public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity implements BaseView,Toolbar.OnMenuItemClickListener,EasyPermission.PermissionCallback {
    protected T mPresenter;
    protected Activity mContext;
    private Unbinder mUnbinder;
    //權(quán)限處理
    private int mRequestCode;
    private String[] mPermissions;
    private PermissionCallBackM mPermissionCallBack;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(initLayoutInflater());
        mUnbinder = ButterKnife.bind(this);
        mContext = this;
        createPresenter();
        if (mPresenter != null) mPresenter.attachView(this);
        BaseApplication.getInstance().addActivity(this);
        initParams();
        initViews();
    }
    protected abstract int initLayoutInflater(); //初始化布局

    protected abstract void initParams(); //初始化參數(shù)

    protected abstract void initViews();  //初始化控件

    protected abstract void createPresenter(); //創(chuàng)建presenter

    /**
     * @param toolbar toolbar 控件
     * @param title   標(biāo)題
     */
    protected void setToolBar(Toolbar toolbar, String title) {
        if (toolbar != null) {
            if (title != null) toolbar.setTitle(title);
            setSupportActionBar(toolbar);
            toolbar.setOnMenuItemClickListener(this);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setDisplayShowHomeEnabled(true);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    onBackPressed();
                }
            });
        }
    }
    //toolbar右側(cè)menu點(diǎn)擊事件
    @Override
    public boolean onMenuItemClick(MenuItem item) {
        return false;
    }

    //統(tǒng)一處理錯(cuò)誤信息
    public void handleError(BaseResultBean errResult) {
        if (errResult == null) return;
        if (this == null) return;
        //可以分門(mén)別類(lèi)的處理 錯(cuò)誤消息稽犁,如session過(guò)期,跳轉(zhuǎn)到登錄頁(yè)面骚亿。其他情況提示即可
        ToastUtils.showToast(mContext, errResult.getMsg());
    }
    //權(quán)限處理開(kāi)始
    //rationale: 申請(qǐng)授權(quán)理由
    protected void requestPermission(int requestCode, String[] permissions, String rationale,
                                     PermissionCallBackM permissionCallback) {
        this.mRequestCode = requestCode;
        this.mPermissionCallBack = permissionCallback;
        this.mPermissions = permissions;

        EasyPermission.with(this)
                .addRequestCode(requestCode)
                .permissions(permissions)
                //.nagativeButtonText(android.R.string.ok)
                //.positveButtonText(android.R.string.cancel)
                .rationale(rationale)
                .request();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        /*
            從Settings界面跳轉(zhuǎn)回來(lái)已亥,標(biāo)準(zhǔn)代碼,就這么寫(xiě)
        */
        if (requestCode == EasyPermission.SETTINGS_REQ_CODE) {
            if (EasyPermission.hasPermissions(this, mPermissions)) {
                //已授權(quán)循未,處理業(yè)務(wù)邏輯
                onEasyPermissionGranted(mRequestCode, mPermissions);
            } else {
                onEasyPermissionDenied(mRequestCode, mPermissions);
            }
        }
    }

    @Override
    public void onEasyPermissionGranted(int requestCode, String... perms) {
        if (mPermissionCallBack != null) {
            mPermissionCallBack.onPermissionGrantedM(requestCode, perms);
        }
    }

    @Override
    public void onEasyPermissionDenied(final int requestCode, final String... perms) {
        //rationale: Never Ask Again后的提示信息
        if (EasyPermission.checkDeniedPermissionsNeverAskAgain(this, "您已關(guān)閉" + PermissionUtils.getRationale(perms) + "陷猫,部分功能將不能正常使用秫舌,點(diǎn)擊設(shè)置進(jìn)入設(shè)置頁(yè)面", android.R.string.ok,
                android.R.string.cancel,
                new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        if (mPermissionCallBack != null) {
                            mPermissionCallBack.onPermissionDeniedM(
                                    requestCode, perms);
                        }
                    }
                }, perms)) {
            return;
        }

        if (mPermissionCallBack != null) {
            mPermissionCallBack.onPermissionDeniedM(requestCode, perms);
        }
    }
    //權(quán)限處理結(jié)束

    @Override
    protected void onDestroy() {
        if (mPresenter != null) mPresenter.detachView();
        if (mUnbinder != null) mUnbinder.unbind();
        super.onDestroy();
    }

}

使用:

封裝很徹底的妖,使用的時(shí)候也很簡(jiǎn)單,下面是我在LoadingActivity里的代碼足陨,獲取到讀寫(xiě)權(quán)限后再進(jìn)入Mainactivity嫂粟,否則退出應(yīng)用:

 requestPermission(
                0,
                new String[]{PermissionUtils.PERMISSION_WRITE_EXTERNAL_STORAGE},
                "",
                new PermissionCallBackM() {
                    @Override
                    public void onPermissionGrantedM(int requestCode, String... perms) {
                        toMainActivity();
                    }
                    @Override
                    public void onPermissionDeniedM(int requestCode, String... perms) {
                        finish();
                    }
                });

1.2 N讀寫(xiě)外部文件

封裝:

a,在res下新建xml文件夾,xml內(nèi)新建file_paths.xml,內(nèi)容如下

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!--表示Environment.getExternalStorageDirectory()目錄或者其子目錄墨缘。-->
    <external-path name="external-paths" path="."/>
    <!--表示Context.getFilesDir()目錄或者其子目錄星虹。-->
    <files-path name="files-paths" path="." />
    <!--表示Context.getExternalFilesDir(null)目錄或者其子目錄零抬。-->
    <external-files-path name="external_files_paths" path="." />
    <!--表示Context.getExternalCacheDir()目錄或者其子目錄。-->
    <external-cache-path name="external-cache-paths" path="." />

</paths>

b,清單文件注冊(cè):

<!--解決安卓N 調(diào)用相冊(cè)異常-->
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.example.burro.demo.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
使用:

在FileUtils工具類(lèi)中的viewFile()內(nèi):

 //解決安卓7.0的問(wèn)題
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mUri = FileProvider.getUriForFile(context,
                    BuildConfig.APPLICATION_ID + ".provider",
                    new File(filePath));
        } else {
            mUri = Uri.fromFile(new File(filePath));
        }

2.圖片處理工具

為啥要說(shuō)它呢宽涌。因?yàn)槲覀円郧坝胕mageloader比較多些平夜。但是picasso是基于okhttp的。因?yàn)橥ㄐ攀腔趏khttp的卸亮,所以可以無(wú)縫對(duì)接忽妒。它可以真正的一句代碼搞定加載圖片。

依賴(lài):

compile 'com.squareup.picasso:picasso:2.5.2'

封裝:

封裝比較簡(jiǎn)易兼贸,可根據(jù)項(xiàng)目調(diào)整

package com.example.burro.demo.appframework.util;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;

import com.squareup.picasso.Picasso;

/**
 * Created by burro on 2017/8/21.
 * 圖片顯示類(lèi)
 */

public class PicassoUtils {
    public static void loadImage(Context mContext, ImageView imageView, String url, int defaultImage) {
        if (mContext != null && imageView != null && !StringUtils.isStrEmpty(url) && defaultImage > 0)
            Picasso.with(mContext).load(url).error(defaultImage).placeholder(defaultImage)
                    .fit()
                    .centerCrop()
                    .into(imageView);
    }

    public static void loadImage(Context mContext, ImageView imageView, String url, Drawable defaultImage) {
        if (mContext != null && imageView != null && !StringUtils.isStrEmpty(url))
            if (defaultImage != null) {
                Picasso.with(mContext).load(url).error(defaultImage).placeholder(defaultImage)
                        .fit()
                        .centerCrop()
                        .into(imageView);
            } else {
                Picasso.with(mContext).load(url)
                        .fit()
                        .centerCrop()
                        .into(imageView);
            }

    }
}
使用:
 PicassoUtils.loadImage(this,imgLogo,movieInfoBean.images.large,null);

3webView的引入段直。webView 我想也是不可或缺的一環(huán),想著把之前的用到的封裝起來(lái)溶诞。突然已有大牛完美的封裝了它鸯檬。還能這干嘛。直接依賴(lài)進(jìn)來(lái)螺垢。效果也挺不錯(cuò)

依賴(lài):
compile 'com.just.agentweb:agentweb:2.0.1'

封裝:
這個(gè)agentweb本身就是給webView作的封裝喧务,詳細(xì)介紹請(qǐng)看https://github.com/Justson/AgentWeb

使用:
下面的代碼取自原博客,我也在Activity和Fragment中測(cè)試驗(yàn)證了枉圃。效果很不錯(cuò)蹂楣,重點(diǎn)是不需要寫(xiě)webView相關(guān)的設(shè)置了。

mAgentWeb = AgentWeb.with(this)//傳入Activity or Fragment
                .setAgentWebParent(mLinearLayout, new LinearLayout.LayoutParams(-1, -1))//傳入AgentWeb 的父控件 讯蒲,如果父控件為 RelativeLayout 痊土, 那么第二參數(shù)需要傳入 RelativeLayout.LayoutParams ,第一個(gè)參數(shù)和第二個(gè)參數(shù)應(yīng)該對(duì)應(yīng)。
                .useDefaultIndicator()// 使用默認(rèn)進(jìn)度條
                .defaultProgressBarColor() // 使用默認(rèn)進(jìn)度條顏色
                .setReceivedTitleCallback(mCallback) //設(shè)置 Web 頁(yè)面的 title 回調(diào)
                .createAgentWeb()//
                .ready()
                .go("http://www.jd.com");

4.錯(cuò)誤日志保存編寫(xiě)

錯(cuò)誤日志的保存很重要墨林,有利于項(xiàng)目的優(yōu)化和升級(jí)赁酝。后面可以根據(jù)情況上傳到服務(wù)器!
這部分的代碼,已經(jīng)很成熟了旭等。我只貼一下:

package com.example.burro.demo.appframework.util;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.lang.Thread.UncaughtExceptionHandler;

/**錯(cuò)誤日志保存到本地
 * Created by burro on 2017/10/20.
 */
public class CrashHandler implements UncaughtExceptionHandler {
    public static final String TAG = "CrashHandler";

    //系統(tǒng)默認(rèn)的UncaughtException處理類(lèi)
    private Thread.UncaughtExceptionHandler mDefaultHandler;
    //CrashHandler實(shí)例
    private static CrashHandler INSTANCE = new CrashHandler();
    //程序的Context對(duì)象
    private Context mContext;
    //用來(lái)存儲(chǔ)設(shè)備信息和異常信息
    private Map<String, String> infos = new HashMap<String, String>();

    //用于格式化日期,作為日志文件名的一部分
    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

    /** 保證只有一個(gè)CrashHandler實(shí)例 */
    private CrashHandler() {
    }

    /** 獲取CrashHandler實(shí)例 ,單例模式 */
    public static CrashHandler getInstance() {
        return INSTANCE;
    }

    /**
     * 初始化
     *
     * @param context
     */
    public void init(Context context) {
        mContext = context;
        //獲取系統(tǒng)默認(rèn)的UncaughtException處理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        //設(shè)置該CrashHandler為程序的默認(rèn)處理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * 當(dāng)UncaughtException發(fā)生時(shí)會(huì)轉(zhuǎn)入該函數(shù)來(lái)處理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        if (!handleException(ex) && mDefaultHandler != null) {
            //如果用戶(hù)沒(méi)有處理則讓系統(tǒng)默認(rèn)的異常處理器來(lái)處理
            mDefaultHandler.uncaughtException(thread, ex);
        } else {
//            try {
//                Thread.sleep(3000);
//            } catch (InterruptedException e) {
//                LogUtils.e(TAG, "error : ", e);
//            }
            //退出程序
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);
        }
    }

    /**
     * 自定義錯(cuò)誤處理,收集錯(cuò)誤信息 發(fā)送錯(cuò)誤報(bào)告等操作均在此完成.
     *
     * @param ex
     * @return true:如果處理了該異常信息;否則返回false.
     */
    private boolean handleException(Throwable ex) {
        if (ex == null) {
            return false;
        }
        //使用Toast來(lái)顯示異常信息
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                ToastUtils.showToast(mContext,"很抱歉,程序出現(xiàn)異常,即將退出");
                Looper.loop();
            }
        }.start();
        //收集設(shè)備參數(shù)信息
        collectDeviceInfo(mContext);
        //保存日志文件
        saveCrashInfo2File(ex);
        return true;
    }

    /**
     * 收集設(shè)備參數(shù)信息
     * @param ctx
     */
    public void collectDeviceInfo(Context ctx) {
        try {
            PackageManager pm = ctx.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
            if (pi != null) {
                String versionName = pi.versionName == null ? "null" : pi.versionName;
                String versionCode = pi.versionCode + "";
                infos.put("versionName", versionName);
                infos.put("versionCode", versionCode);
            }
        } catch (PackageManager.NameNotFoundException e) {
            LogUtils.e(TAG, "an error occured when collect package info", e);
        }
        Field[] fields = Build.class.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                infos.put(field.getName(), field.get(null).toString());
                LogUtils.d(TAG, field.getName() + " : " + field.get(null));
            } catch (Exception e) {
                LogUtils.e(TAG, "an error occured when collect crash info", e);
            }
        }
    }

    /**
     * 保存錯(cuò)誤信息到文件中
     *
     * @param ex
     * @return  返回文件名稱(chēng),便于將文件傳送到服務(wù)器
     */
    private String saveCrashInfo2File(Throwable ex) {

        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> entry : infos.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            sb.append(key + "=" + value + "\n");
        }

        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        ex.printStackTrace(printWriter);
        Throwable cause = ex.getCause();
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.close();
        String result = writer.toString();
        sb.append(result);
        try {
            long timestamp = System.currentTimeMillis();
            String time = formatter.format(new Date());
            String fileName = "crash-" + time + "-" + timestamp + ".log";
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                String path = FileUtils.getInstance().getCrashLogPath();
                File dir = new File(path);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                FileOutputStream fos = new FileOutputStream(path + fileName);
                fos.write(sb.toString().getBytes());
                fos.close();
            }
            return fileName;
        } catch (Exception e) {
            LogUtils.e(TAG, "an error occured while writing file...", e);
        }
        return null;
    }
}

需要注意的是瓦盛,在application類(lèi)里要做初始化:

CrashHandler.getInstance().init(this);

5.數(shù)據(jù)庫(kù)GreenDao的封裝使用

GreenDao的使用并非三言?xún)烧Z(yǔ)就能說(shuō)明白,推薦大家仔細(xì)讀讀下面這篇文章篓吁。然后寫(xiě)個(gè)demo測(cè)試下滑臊。
http://blog.csdn.net/njweiyukun/article/details/51893092
為了保證框架的純凈度,就不在內(nèi)部寫(xiě)相關(guān)測(cè)試了

6.使用到的的常用工具類(lèi)也是必不可少的弃榨。因?yàn)槎际且恍┙?jīng)典且大家熟知的代碼菩收。我就不一一詳細(xì)介紹。有興趣的同學(xué)可以看看源碼 或者進(jìn)行補(bǔ)充

好啦鲸睛。至此告一段落娜饵。下面會(huì)花一些時(shí)間好好研究daggar2,因?yàn)樗哪康氖墙怦罟ぷ鞴俦病⒋蟠髢?yōu)化我們的程序結(jié)構(gòu)箱舞。提高代碼質(zhì)量遍坟!

相關(guān)鏈接

github源碼地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市晴股,隨后出現(xiàn)的幾起案子愿伴,更是在濱河造成了極大的恐慌,老刑警劉巖电湘,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件公般,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡胡桨,警方通過(guò)查閱死者的電腦和手機(jī)官帘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)昧谊,“玉大人刽虹,你說(shuō)我怎么就攤上這事∧匚埽” “怎么了涌哲?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)尚镰。 經(jīng)常有香客問(wèn)我阀圾,道長(zhǎng),這世上最難降的妖魔是什么狗唉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任初烘,我火速辦了婚禮,結(jié)果婚禮上分俯,老公的妹妹穿的比我還像新娘肾筐。我一直安慰自己,他們只是感情好缸剪,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布吗铐。 她就那樣靜靜地躺著,像睡著了一般杏节。 火紅的嫁衣襯著肌膚如雪唬渗。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天奋渔,我揣著相機(jī)與錄音镊逝,去河邊找鬼。 笑死卒稳,一個(gè)胖子當(dāng)著我的面吹牛蹋半,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播充坑,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼减江,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了捻爷?” 一聲冷哼從身側(cè)響起辈灼,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎也榄,沒(méi)想到半個(gè)月后巡莹,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡甜紫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年降宅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片囚霸。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡腰根,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拓型,到底是詐尸還是另有隱情额嘿,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布劣挫,位于F島的核電站册养,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏压固。R本人自食惡果不足惜球拦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帐我。 院中可真熱鬧刘莹,春花似錦、人聲如沸焚刚。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)矿咕。三九已至抢肛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碳柱,已是汗流浹背捡絮。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留莲镣,地道東北人福稳。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瑞侮,于是被迫代替她去往敵國(guó)和親的圆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鼓拧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,528評(píng)論 25 707
  • 框架:提供一定能力的小段程序 http://www.cnblogs.com/jincheng-yangchaofa...
    姑娘請(qǐng)別為難小僧閱讀 7,186評(píng)論 0 132
  • 一.榜單介紹 排行榜包括四大類(lèi): 單一框架:僅提供路由、網(wǎng)絡(luò)層越妈、UI層季俩、通信層或其他單一功能的框架 混合開(kāi)發(fā)框架:...
    偉子男閱讀 5,239評(píng)論 0 161
  • 附上原文作者連接:作者:金誠(chéng) 一.榜單介紹 排行榜包括四大類(lèi): 單一框架:僅提供路由、網(wǎng)絡(luò)層梅掠、UI層酌住、通信層或其他...
    這個(gè)美嘉不姓陳閱讀 2,251評(píng)論 1 35
  • 【禪舞.不是舞蹈.到底是什么?】 尋找內(nèi)在的身體 在舞動(dòng)里阎抒,釋放人潛在內(nèi)心深處的焦慮酪我、憂慮、傷痛且叁、悲哀的情緒都哭; 在...
    坤靈j閱讀 3,054評(píng)論 0 0