首页 文章 精选 留言 我的

精选列表

搜索[云上实践],共10000篇文章
优秀的个人博客,低调大师

8.kotlin安卓实践课程-用kotlin写第一个fragment

简介 主要会通过安卓实战来讲解kotlin语法和实际应用,本教程设及知识点包括框架模式mvp+mvvm, Databinding(数据绑定框架),Dagger2(依赖注入框架),DeepLink(页面路由框架),Rxjava,RxAndroid(异步操作框架),Retrofit,Okhtttp等,不过本教程重点在kotlin所以这些框架需要了解可自行百度。 针对人群:Android中级以上,kotlin入门 我们马上开始完成第一个kotlin代码实现的fragment 首先先看一下代码 /** * * Created by bigman on 18-05-18. */ class AndroidFragment : BaseBingingFragment<ViewRecyclerBinding>(), AndroidContract.View { private var mList = ArrayList<AndroidBean>() private lateinit var mAdapter: AndroidAdapter private var mPage = 1 @Inject lateinit var mPresenter: AndroidPresenter override fun createDataBinding(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): ViewRecyclerBinding { return ViewRecyclerBinding.inflate(inflater!!, container, false) } override fun initView() { mAdapter = AndroidAdapter(mList) context.getMainComponent().plus(AndroidModule(this)).inject(this) with(mBinding) { recyclerView.adapter = mAdapter recyclerView.layoutManager = LinearLayoutManager(context) recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) //是否滚动到底部 if (!recyclerView?.canScrollVertically(1)!!) { mPresenter.getData(++mPage, ANDROID) } } override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) { super.onScrollStateChanged(recyclerView, newState) } }) } //请求数据 mPresenter.getData(mPage, ANDROID) mAdapter.setOnItemClickListener { pos -> val url = URLEncoder.encode(mList[pos].url) GankRouter.router(context, GankClientUri.DETAIL + url) } } override fun setData(results: List<AndroidBean>) { mList.addAll(results) mAdapter.notifyDataSetChanged() } override fun onDestroy() { super.onDestroy() mPresenter.unSubscribe() } companion object { val ANDROID = "ANDROID" fun newInstance(): AndroidFragment { val fragment = AndroidFragment() val bundle = Bundle() fragment.arguments = bundle return fragment } } } AndroidFragment 代码结构其实和MainActivity的差不多,首先是两个主要方法createDataBinding和initView,他同样是基类声明的两个抽象方法,我们看看基类 BaseBingingFragment的代码: /** * Created by bigman on 18-05-17. */ abstract class BaseBingingFragment<B:ViewDataBinding> : Fragment(){ lateinit var mBinding : B override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View { mBinding = createDataBinding(inflater,container,savedInstanceState) initView() return mBinding.root } override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) } abstract fun createDataBinding(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): B abstract fun initView() } 当然它的实现和activity的基类一样,就是实现了databinding框架的页面绑定,不记得的同学可以翻看一下前面,我们再看基类提供的抽象方法的具体实现 override fun createDataBinding(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): ViewRecyclerBinding { return ViewRecyclerBinding.inflate(inflater!!, container, false) } 这里就是把view_recycler.xml由Databinding自动生成类ViewRecyclerBinding和页面绑定起来 然后再看看initView方法实现代码 override fun initView() { mAdapter = AndroidAdapter(mList) context.getMainComponent().plus(AndroidModule(this)).inject(this) with(mBinding) { recyclerView.adapter = mAdapter recyclerView.layoutManager = LinearLayoutManager(context) recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) //是否滚动到底部 if (!recyclerView?.canScrollVertically(1)!!) { mPresenter.getData(++mPage, ANDROID) } } override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) { super.onScrollStateChanged(recyclerView, newState) } }) } //请求数据 mPresenter.getData(mPage, ANDROID) mAdapter.setOnItemClickListener { pos -> val url = URLEncoder.encode(mList[pos].url) GankRouter.router(context, GankClientUri.DETAIL + url) } } 首先是实例化了一个adapter适配器,然后把通过context.getMainComponent().plus(AndroidModule(this)).inject(this)实现了依赖注入,然后是通过一个with函数包含的代码块实现了 recyclerView的初始化和滚动监听 语法点: with函数 with函数是将某对象作为函数的参数,在函数块内可以通过 this 指代该对象。返回值为函数块的最后一行或指定return表达式。 意思就是说如果要操作with的对象参数直接调用就行,不用多余的修饰符,比如这里的recyclerView就是mBinding对象的成员变量,完整写法应该是mBinding . recyclerView 剩下的需要注意这段代码 companion object { val ANDROID = "ANDROID" fun newInstance(): AndroidFragment { val fragment = AndroidFragment() val bundle = Bundle() fragment.arguments = bundle return fragment } } 这个伴生对象我们前面说过,这里再说一次,它相当于java的静态成员变量,这里的代码大家可以对比一下java的写法,相信java的写法大家都很熟悉了 欢迎一起交流,有问题加群交流 kotlin实战交流群群二维码.png

优秀的个人博客,低调大师

深入理解JVM虚拟机13:再谈四种引用及GC实践

Java中的四种引用类型 一、背景 Java的内存回收不需要程序员负责,JVM会在必要时启动Java GC完成垃圾回收。Java以便我们控制对象的生存周期,提供给了我们四种引用方式,引用强度从强到弱分别为:强引用、软引用、弱引用、虚引用。 二、简介 1.强引用 StrongReference StrongReference是Java的默认引用形式,使用时不需要显示定义。任何通过强引用所使用的对象不管系统资源有多紧张,Java GC都不会主动回收具有强引用的对象。 public class StrongReferenceTest { public static int M = 1024*1024; public static void printlnMemory(String tag){ Runtime runtime = Runtime.getRuntime(); int M = StrongReferenceTest.M; System.out.println("\n"+tag+":"); System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)"); } public static void main(String[] args){ StrongReferenceTest.printlnMemory("1.原可用内存和总内存"); //实例化10M的数组并与strongReference建立强引用 byte[] strongReference = new byte[10*StrongReferenceTest.M]; StrongReferenceTest.printlnMemory("2.实例化10M的数组,并建立强引用"); System.out.println("strongReference : "+strongReference); System.gc(); StrongReferenceTest.printlnMemory("3.GC后"); System.out.println("strongReference : "+strongReference); //strongReference = null;后,强引用断开了 strongReference = null; StrongReferenceTest.printlnMemory("4.强引用断开后"); System.out.println("strongReference : "+strongReference); System.gc(); StrongReferenceTest.printlnMemory("5.GC后"); System.out.println("strongReference : "+strongReference); } } 运行结果: 2.弱引用 WeakReference 如果一个对象只具有弱引用,无论内存充足与否,Java GC后对象如果只有弱引用将会被自动回收。 public class WeakReferenceTest { public static int M = 1024*1024; public static void printlnMemory(String tag){ Runtime runtime = Runtime.getRuntime(); int M = WeakReferenceTest.M; System.out.println("\n"+tag+":"); System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)"); } public static void main(String[] args){ WeakReferenceTest.printlnMemory("1.原可用内存和总内存"); //创建弱引用 WeakReference<Object> weakRerference = new WeakReference<Object>(new byte[10*WeakReferenceTest.M]); WeakReferenceTest.printlnMemory("2.实例化10M的数组,并建立弱引用"); System.out.println("weakRerference.get() : "+weakRerference.get()); System.gc(); StrongReferenceTest.printlnMemory("3.GC后"); System.out.println("weakRerference.get() : "+weakRerference.get()); } } 运行结果: 3.软引用 SoftReference 软引用和弱引用的特性基本一致, 主要的区别在于软引用在内存不足时才会被回收。如果一个对象只具有软引用,Java GC在内存充足的时候不会回收它,内存不足时才会被回收。 public class SoftReferenceTest { public static int M = 1024*1024; public static void printlnMemory(String tag){ Runtime runtime = Runtime.getRuntime(); int M = StrongReferenceTest.M; System.out.println("\n"+tag+":"); System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)"); } public static void main(String[] args){ SoftReferenceTest.printlnMemory("1.原可用内存和总内存"); //建立软引用 SoftReference<Object> softRerference = new SoftReference<Object>(new byte[10*SoftReferenceTest.M]); SoftReferenceTest.printlnMemory("2.实例化10M的数组,并建立软引用"); System.out.println("softRerference.get() : "+softRerference.get()); System.gc(); SoftReferenceTest.printlnMemory("3.内存可用容量充足,GC后"); System.out.println("softRerference.get() : "+softRerference.get()); //实例化一个4M的数组,使内存不够用,并建立软引用 //free=10M=4M+10M-4M,证明内存可用量不足时,GC后byte[10*m]被回收 SoftReference<Object> softRerference2 = new SoftReference<Object>(new byte[4*SoftReferenceTest.M]); SoftReferenceTest.printlnMemory("4.实例化一个4M的数组后"); System.out.println("softRerference.get() : "+softRerference.get()); System.out.println("softRerference2.get() : "+softRerference2.get()); } } 运行结果: 4.虚引用 PhantomReference 从PhantomReference类的源代码可以知道,它的get()方法无论何时返回的都只会是null。所以单独使用虚引用时,没有什么意义,需要和引用队列ReferenceQueue类联合使用。当执行Java GC时如果一个对象只有虚引用,就会把这个对象加入到与之关联的ReferenceQueue中。 public class PhantomReferenceTest { public static int M = 1024*1024; public static void printlnMemory(String tag){ Runtime runtime = Runtime.getRuntime(); int M = PhantomReferenceTest.M; System.out.println("\n"+tag+":"); System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)"); } public static void main(String[] args) throws InterruptedException { PhantomReferenceTest.printlnMemory("1.原可用内存和总内存"); byte[] object = new byte[10*PhantomReferenceTest.M]; PhantomReferenceTest.printlnMemory("2.实例化10M的数组后"); //建立虚引用 ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>(); PhantomReference<Object> phantomReference = new PhantomReference<Object>(object,referenceQueue); PhantomReferenceTest.printlnMemory("3.建立虚引用后"); System.out.println("phantomReference : "+phantomReference); System.out.println("phantomReference.get() : "+phantomReference.get()); System.out.println("referenceQueue.poll() : "+referenceQueue.poll()); //断开byte[10*PhantomReferenceTest.M]的强引用 object = null; PhantomReferenceTest.printlnMemory("4.执行object = null;强引用断开后"); System.gc(); PhantomReferenceTest.printlnMemory("5.GC后"); System.out.println("phantomReference : "+phantomReference); System.out.println("phantomReference.get() : "+phantomReference.get()); System.out.println("referenceQueue.poll() : "+referenceQueue.poll()); //断开虚引用 phantomReference = null; System.gc(); PhantomReferenceTest.printlnMemory("6.断开虚引用后GC"); System.out.println("phantomReference : "+phantomReference); System.out.println("referenceQueue.poll() : "+referenceQueue.poll()); } } 运行结果: 三、小结 强引用是 Java 的默认引用形式,使用时不需要显示定义,是我们平时最常使用到的引用方式。不管系统资源有多紧张,Java GC都不会主动回收具有强引用的对象。 弱引用和软引用一般在引用对象为非必需对象的时候使用。它们的区别是被弱引用关联的对象在垃圾回收时总是会被回收,被软引用关联的对象只有在内存不足时才会被回收。 虚引用的get()方法获取的永远是null,无法获取对象实例。Java GC会把虚引用的对象放到引用队列里面。可用来在对象被回收时做额外的一些资源清理或事物回滚等处理。 由于无法从虚引获取到引用对象的实例。它的使用情况比较特别,所以这里不把虚引用放入表格进行对比。这里对强引用、弱引用、软引用进行对比: 引用类型 GC时JVM内存充足 GC时JVM内存不足 强引用 不被回收 不被回收 弱引用 被回收 被回收 软引用 微信公众号【黄小斜】大厂程序员,互联网行业新知,终身学习践行者。关注后回复「Java」、「Python」、「C++」、「大数据」、「机器学习」、「算法」、「AI」、「Android」、「前端」、「iOS」、「考研」、「BAT」、「校招」、「笔试」、「面试」、「面经」、「计算机基础」、「LeetCode」 等关键字可以获取对应的免费学习资料。 ​

优秀的个人博客,低调大师

【案例学习】美国大都会人寿保险公司的 Docker EE 实践

写在前面 MetLife(美国大都会人寿保险公司)是一家拥有150年历史的公司,它是领先的保险及其它金融服务的提供商,为遍布全美的数以百万计的个人和企业客户提供服务,包括美国财富五百强中排名前100位的88家公司。作为一家全球性公司,MetLife 向世界各地提供金融、保险服务——其中有一些是终身服务。有着如此庞大的业务规模,MetLife 需要多种组合的IT基础设施来维持它的日常运作。 降低现有的技术运维成本 今年4月,来自 MetLife 的亚伦·艾代斯(Aaron Aedes)谈到了他们第一次涉足 Docker 容器的经历——即使用一款通过Azure 交付的名为 GSSP 的新应用程序。六个月后,MetLife 来到 DockerCon 欧洲大会的舞台并分享他们使用 Docker 容器的经验——从最初的部署到促使他们主动寻找在 M

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册