一、实践介绍

1.1项目中心信息

本项目完结了影视综艺榜单及其历史数据查询,完结个人页面展示、个人页面粉丝和重视列表、个人页面已发布视频列表及其详情页

1.2项目服务地址

github.com/gujunhe/dou…

1.3GitHub地址

github.com/gujunhe/dou…

二、实践分工

团队成员 首要贡献
担任基础架构、网络框架、room框架搭建、个人页面已发布视频列表及其详情页、粉丝和重视列表
XX 电影榜单、粉丝和重视列表
XX 电视剧榜单、粉丝和重视列表
XX 综艺榜单、导航栏搭建
XX 榜单数据管理、导航栏搭建
XX 影视榜单布局、个人界面布局

三、实践完结

3.1 技术选型与相关开发文档

3.1.1技术选型

Navigation 提供路由导航服务 ViewModel 具备生命周期感知能力的数据存储组件,用于寄存使用程序页面所需的数据

关于我在字节跳动青训营做了个抖音这件事

Retrofit

完结网络恳求。

Gson

用来合作Retrofit、Room完结序列化和反序列化,自定义Type Converter将榜单List数据转化为Json存储到数据库中。

Room

数据库,与LiveData、ViewModel结合运用,当Room数据库中的数据发生变化时,可以经过LiveData组件告诉View层,完结数据的主动更新。

LiveData

LiveData是一个可被调查的数据容器类,在ViewModel中的数据发生变化时告诉页面。

DataBinding

运用声明性格式将布局中的界面组件绑定到使用中的数据源,使页面与布局文件之间的耦合度进一步下降。

Paing

列表分页组件,完结数据预加载、按需加载,结合Room运用,数据直接来源于Room数据库。当网络数据恳求成功后,会直接将其写入Room数据库,因为运用了LiveData,当数据有变化时,ViewModel会主动得到告诉,主动完结数据的更新。

Picasso

加载网络图片,完结占位图、图片主动缓存。

3.1.2开发文档

协作模式

项目经过GitHub进行团队协作开发。

3.2 架构设计

本项目选用MVVM的架构,在ViewModel层和Model层之间引入Repository层。在Repository层处理本地数据和网络数据之间的事务逻辑,让Repository层对ViewModel层担任,使ViewModel只需要关心自己的事务逻辑,而不必关心数据的详细来源。数据在发生变化时,界面可以主动得到告诉并进行更新,数据模型驱动界面更新。

关于我在字节跳动青训营做了个抖音这件事
这里以影视综艺榜单代码为例

  1. RankFragment持有RankViewModel,获取到来自RankViewModel的数据后将数据加载进recyclerview。
rankViewModel.getRankItemByTypeAndVersion(type, "141").observe(getViewLifecycleOwner(), new Observer<List<RankItem.DataBean.ListBean>>() {
    @Override
    public void onChanged(List<RankItem.DataBean.ListBean> listBeans) {
        if(listBeans!=null) {
            myItemRecyclerViewAdapter = new MyItemRecyclerViewAdapter(listBeans);
            recyclerView.setAdapter(myItemRecyclerViewAdapter);
        }
    }
});
  1. RankViewModel持有rankRepository,经过rankRepository获取到榜单数据。
public LiveData<List<RankItem.DataBean.ListBean>> getRankItemByTypeAndVersion(String type,String version) {
    return rankRepository.getRankItemByTypeAndVersion(type,version);
}
  1. RankRepository进行数据恳求。
public LiveData<List<RankItem.DataBean.ListBean>> getRankItemByTypeAndVersion(String type,String version) {
    return rankRepository.getRankItemByTypeAndVersion(type,version);
}
public void refreshitembyTypeAndVersion(String type,String version)
{
    apiService.getrankitem("application/json",MyApplication.clientToken.getValue(),type,version).enqueue(new Callback<RankItem>() {
        @Override
        public void onResponse(Call<RankItem> call, Response<RankItem> response) {
            if(response.body().getData().getList()!=null)
            {
                insertRankItem(response.body().getData().getList());//刺进数据库
                Log.d(TAG,response.body().getData().getList().toString());
            }
        }
        @Override
        public void onFailure(Call<RankItem> call, Throwable t) {
        }
    });
}
private  void insertRankItem(List<RankItem.DataBean.ListBean> list )
{
    AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            for(int i=0;i<list.size();i++) {
                Log.d(TAG, list.get(i).toString());
                rankItemDao.insertRankItem(list.get(i));
            }
        }
    });
}
  1. RankItemDao获取数据返回的是LiveData目标,当数据库中的数据更新后,ViewModel会主动得到告诉,主动完结数据的更新。
@Dao
public interface RankItemDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertRankItem(RankItem.DataBean.ListBean rankitem);
    //获取表中一切数据
    @Query("SELECT *FROM rankitem WHERE type = :type")
    LiveData<List<RankItem.DataBean.ListBean>> findAllbytype(String type);
}

3.3 项目代码介绍

  • adapter:各种适配器,包括自定义的ViewBindingAdapter完结直接在布局文件中经过image调用静态办法加载网络图片,FollowingPagedListAdapter和FansPagedListAdapter完结对粉丝和重视列表进行分页加载。

关于我在字节跳动青训营做了个抖音这件事

  • 数据库:数据库Database、操作数据库的相关Dao、自定义@TypeConverter

    关于我在字节跳动青训营做了个抖音这件事

  • model

关于我在字节跳动青训营做了个抖音这件事

  • network:ApiService 接口和RetrofitClient

关于我在字节跳动青训营做了个抖音这件事

  • ui:activity和fragment以及对应的Viewmodel层、Repository层(部分没有运用),分页加载的SourceFactory,以及一些布局所需要的函数。

关于我在字节跳动青训营做了个抖音这件事

  • view:自定义View,完结自定义底部导航栏、个人界面相关view、完结顶部下拉图片放大松手图片回弹的view

关于我在字节跳动青训营做了个抖音这件事

四、测验结果

功用测验

本项目一切已完结的功用经过测验无报错

功用测验

有运用Androidstudio自带的Profiler和手机自带的GPU渲染进行功用测验

五、演示demo

录屏

(影视榜单api超出约束,无法演示榜单版别切换)

演示demo链接

中心功用截图

影视综艺榜单页面

关于我在字节跳动青训营做了个抖音这件事

个人页面及个人页面已发布视频列表

关于我在字节跳动青训营做了个抖音这件事

重视及粉丝列表

关于我在字节跳动青训营做了个抖音这件事

个人已发布视频详情页

关于我在字节跳动青训营做了个抖音这件事

六、实践总结与反思

6.1 目前仍存在的问题

  • 对clientsecret、access_token没有加密保存。
  • 界面不行漂亮。
  • 没有编写 access_token过期后主动刷新的代码。

6.2 已识别出的优化项

  • 减少页面布局的嵌套,优化recyclerview的加载速度。
  • 对一些可以复用的代码进行可扩展的封装,减少代码量,提高开发功率。
  • 优化项目结构

6.3 架构演进的可能性

6.4 项目过程中的反思与总结

第一次当组长经过团队协作完结项目,在经过github进行团队协作中还是遇到了不少困难,同时也学到了许多。在项目刚开始构建时,本想用模块化进行开发,以便利团队协作、开发和维护,但是后来觉得项目不大,就没有选用,后边导致团队协作遇到困难。

在模仿抖音个人界面完结下拉放大、松手主动回弹的作用时,查找了许多材料和计划,最终完结了比较好的作用,在这个过程中加深了对自定义view的了解,让自己的技术得到了提升。

因为是第一次完结一个不算小的项目,在架构方面、代码封装方面做得不太好,仅仅为了完结所要求的功用,没有对代码进行太多的扩展,在写代码时也没有编写详细的注释,这些方面应该要去改进。

七、其他弥补材料(选填)