国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

開源Kotlin小項(xiàng)目,非常適合練手

xiaoxiaozi / 2661人閱讀

摘要:一個(gè)非常小型的項(xiàng)目,但是該有的都有。快速跳轉(zhuǎn)至頂部,底部,指定位置。讀寫緩存的效率遠(yuǎn)低于,所以采用實(shí)現(xiàn)的緩存機(jī)制,速度快了大概,倍。序列化性能性能測(cè)試,,為了避免干擾,我們使用進(jìn)行測(cè)試。

一個(gè)非常小型的Kotlin項(xiàng)目,但是該有的都有。如果您覺得有意思就幫我star下,人多了我就會(huì)放更多的福利哦。github

先上福利。Release1.0

特點(diǎn)

列表顯示圖片,點(diǎn)擊查看更多。

快速跳轉(zhuǎn)至頂部,底部,指定位置。

收藏,查看歷史記錄。

設(shè)置壁紙。

離線緩存。

組成

語言:Kotlin,Java

網(wǎng)絡(luò)請(qǐng)求:HttpUrlConnection

數(shù)據(jù)庫:Sqlite

數(shù)據(jù)源:Jsoup

第三方庫:Glide

概述

1) 網(wǎng)絡(luò)請(qǐng)求

網(wǎng)絡(luò)框架并沒有使用RxRetrofit等,為了保證精簡(jiǎn)高效直接使用的HttpUrlConnection

get

val request = AsyncNetwork()
request.request(Constants.HOST_MOBILE_URL, null)
request.setRequestCallback(object : IRequestCallback {
    override fun onSuccess(httpURLConnection: HttpURLConnection?, response: String) {
        //todo
    }
})

post

val request = AsyncNetwork()
request.request(Constants.HOST_MOBILE_URL, mutableMapOf())
request.setRequestCallback(object : IRequestCallback {
    override fun onSuccess(httpURLConnection: HttpURLConnection?, response: String) {
        //todo
    }
})

2) 數(shù)據(jù)庫

數(shù)據(jù)庫沒有使用第三方框架,直接使用的sql語句。

CREATE TABLE tb_class_page_list ( 
                    _id           INTEGER PRIMARY KEY ASC AUTOINCREMENT,
                    href          STRING  UNIQUE,
                    description   STRING,
                    image_url     STRING,
                    id_class_page INTEGER REFERENCES tb_class_page (_id) ON DELETE CASCADE ON UPDATE CASCADE,
                    [index]       INTEGER);

3) 讀寫緩存

Serializable的效率遠(yuǎn)低于Parcelable,所以采用Parcelable實(shí)現(xiàn)的緩存機(jī)制,速度快了大概7,8倍。

讀取緩存

val helper = PageListCacheHelper(container?.context?.filesDir?.absolutePath)
val pageModel: Any? = helper.get(key)

寫入緩存

val helper = PageListCacheHelper(context.filesDir.absolutePath)
helper.put(key, object)

刪除緩存

val helper = PageListCacheHelper(context.filesDir.absolutePath)
helper.remove(key)

4) jsoup獲取數(shù)據(jù)

由于數(shù)據(jù)是用從html頁面中提取的,所以速度偏慢,為了不影響體驗(yàn)做了一套緩存機(jī)制,來做到流暢體驗(yàn)。

Document doc = Jsoup.parse(html);
Elements elements = body.getElementsByTag("a");
String text = elements.get(0).text();
String imageUrl = elements.get(0).attr("src");
...

5) 組件

Activity fragment替代activity來顯示新界面

因?yàn)閍ctivity需要在Manifiest中注冊(cè),所以當(dāng)有多個(gè)activity的時(shí)候,就需要編寫很長(zhǎng)的Manifiest文件,嚴(yán)重影響了Manifiest的可讀性,界面的風(fēng)格也比較笨重。所以一個(gè)新頁面就注冊(cè)一個(gè)activity不太合適,我們通過用activity做為容器添加不同的Fragment來達(dá)到注冊(cè)一個(gè)activity啟動(dòng)多個(gè)不同頁面的效果。生命周期由activity管理,更方便簡(jiǎn)潔。

open class BaseFragmentActivity : BaseActionActivity() {

    companion object {

        private const val EXTRA_FRAGMENT_NAME = "extra_fragment_name"
        private const val EXTRA_FRAGMENT_ARG = "extra_fragment_arguments"

        @JvmOverloads
        @JvmStatic
        fun newInstance(context: Context, fragment: Class<*>, bundle: Bundle? = null,
                                      clazz: Class = getActivityClazz()): Intent {
            val intent = Intent(context, clazz)
            intent.putExtra(EXTRA_FRAGMENT_NAME, fragment.name)
            intent.putExtra(EXTRA_FRAGMENT_ARG, bundle)
            return intent
        }

        protected open fun getActivityClazz(): Class {
            return BaseFragmentActivity::class.java
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.cc_activity_base_fragment)
        val fragmentName = intent.getStringExtra(EXTRA_FRAGMENT_NAME)
        var fragment: Fragment? = null
        if (TextUtils.isEmpty(fragmentName)) {
            //set default fragment
            //fragment = makeFragment(MainFragment::class.java!!.getName())
        } else {
            val args = intent.getBundleExtra(EXTRA_FRAGMENT_ARG)
            try {
                fragment = makeFragment(fragmentName)
                if (args != null)
                    fragment?.arguments = args
            } catch (e: Exception) {
                e.printStackTrace()
            }

        }

        if (fragment == null) return

        supportFragmentManager
                .beginTransaction()
                .replace(R.id.fragment_container, fragment)
                .commit()
    }

    fun makeFragment(name: String): Fragment? {
        try {
            val fragmentClazz = Class.forName(name)
            return fragmentClazz.newInstance() as Fragment
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return null
    }

}

6) 序列化性能

性能測(cè)試,Serializable VS Externalizable,為了避免干擾,我們使用AndroidTest進(jìn)行測(cè)試。

模型

class Model1 implements Serializable {
    String text;
    int code;
    boolean bool;
    Model1 child;
}

class Model2 extends Model1 implements Externalizable {

    public Model2() {
    }

    @Override
    public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException {
        text = input.readUTF();
        code = input.readInt();
        bool = input.readBoolean();

        child = new Model2();
        child.text = input.readUTF();
        child.code = input.readInt();
        child.bool = input.readBoolean();
    }

    @Override
    public void writeExternal(ObjectOutput output) throws IOException {
        output.writeUTF(text);
        output.writeInt(code);
        output.writeBoolean(bool);
        if (child != null) {
            output.writeUTF(child.text);
            output.writeInt(child.code);
            output.writeBoolean(child.bool);
        }
    }
}

測(cè)試

@Test
public void serializableVSExternalizable() throws Exception {
    List testModel1 = new ArrayList<>();
    for (int i = 0; i < 50000; i++) {
        Model1 model1 = new Model1();
        model1.text = "Hello World " + i;
        model1.code = i;
        model1.bool = false;

        Model1 child = new Model1();
        child.text = "Hello World Child" + i;
        child.code = i;
        child.bool = false;

        model1.child = child;
        testModel1.add(model1);
    }
    long startTime = System.currentTimeMillis();
    File file = new File("/sdcard/serializable");
    ObjectOutputStream oStream = new ObjectOutputStream(new FileOutputStream(file));
    oStream.writeObject(testModel1);
    oStream.close();
    Log.e("serializable", "write time " + (System.currentTimeMillis() - startTime));
    startTime = System.currentTimeMillis();
    ObjectInputStream iStream = new ObjectInputStream(new FileInputStream(file));
    testModel1 = (List) iStream.readObject();
    iStream.close();
    Log.e("serializable", "read time " + (System.currentTimeMillis() - startTime));
    testModel1 = null;

    List testModel2 = new ArrayList<>();
    for (int i = 0; i < 50000; i++) {
        Model2 model2 = new Model2();
        model2.text = "Hello World " + i;
        model2.code = i;
        model2.bool = false;

        Model2 child = new Model2();
        child.text = "Hello World Child" + i;
        child.code = i;
        child.bool = false;

        model2.child = child;
        testModel2.add(model2);
    }
    startTime = System.currentTimeMillis();
    file = new File("/sdcard/externalizable");
    oStream = new ObjectOutputStream(new FileOutputStream(file));
    oStream.writeObject(testModel2);
    oStream.close();
    Log.e("externalizable", "write time " + (System.currentTimeMillis() - startTime));
    startTime = System.currentTimeMillis();
    iStream = new ObjectInputStream(new FileInputStream(file));
    testModel2 = (List) iStream.readObject();
    iStream.close();
    Log.e("externalizable", "read time " + (System.currentTimeMillis() - startTime));
}

結(jié)果

序列化5000個(gè)對(duì)象
Serializable:寫入耗時(shí)4026 ms,讀取耗時(shí)177 ms
Externalizable:寫入耗時(shí)2680 ms,讀取耗時(shí)79 ms

序列化50000個(gè)對(duì)象
Serializable:寫入耗時(shí)46872 ms,讀取耗時(shí)1807 ms
Externalizable:寫入耗時(shí)41334 ms,讀取耗時(shí)792 ms

從結(jié)果上可以看到Externalizalbe相比于Serializable是稍微快一些點(diǎn)不管是寫入還是讀取速度。對(duì)象存儲(chǔ)還可以使用一些對(duì)象關(guān)系映射(ORM)型的數(shù)據(jù)庫。如GreenDao等等。

7) Java中的深拷貝

由于System.arrayCopy()該方法拷貝數(shù)組的時(shí)候,如果是基本數(shù)據(jù)類型則是深拷貝,如果是對(duì)象類型則會(huì)是淺拷貝,無法做到深拷貝,所以想深拷貝一個(gè)數(shù)組就得循環(huán)創(chuàng)建對(duì)象并賦值,這顯得很麻煩。所以項(xiàng)目中使用序列化的方法進(jìn)行深拷貝。PS:Serializable序列化方式讀取的時(shí)候并不會(huì)調(diào)用對(duì)象構(gòu)造方法,而Externalizable序列化方式讀取時(shí)會(huì)調(diào)用對(duì)象的無參構(gòu)造方法。

@SuppressWarnings("unchecked")
public static  T deepCopyOrThrow(T src) throws IOException, ClassNotFoundException {
    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(byteOut);
    out.writeObject(src);

    ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
    ObjectInputStream in = new ObjectInputStream(byteIn);
    return (T) in.readObject();
}

public static  T deepCopy(T src) {
    try {
        return deepCopyOrThrow(src);
    } catch (Exception ignore) {
        ignore.printStackTrace();
        return null;
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/68026.html

相關(guān)文章

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<