Android

MVC

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)

M层处理数据,业务逻辑等;V层处理界面的显示结果;C层起到桥梁的作用,来控制V层和M层通信以此来达到分离视图显示和业务逻辑层

请介绍下 Android 的数据存储方式
a. File存储
b. SharedPreference存储
c. ContentProvider存储
d. SQLiteDataBase 存储
e. 网络存储

Android的事件分发机制,消息机制(Handler)

AsyncTask 异步任务

Android给我们提供的一个处理异步任务的类。通过此类,可以实现UI线程和后台线程进行通讯,后台线程执行异步任务,并把结果返回给UI线程。

AsyncTask是利用Handler的消息异步处理机制,将操作结果,利用Message传回主线程,从而进行UI线程的更新的。

Handler的消息异步处理机制

Android的消息机制的上层接口,通过发送和处理Message和Runnable对象来关联相对应的的线程MessageQueue;

(1)可以让对应的Message和Runnable在未来的某个时间点进行相应处理

(2)让自己想要处理的耗时操作放在子线程,让更新UI的操作放在主线程;

  1. 作用:对消息(消息可以是我们想做的一些UI更新,也可以是其他的一些不可见的操作,如操作数据库等)的异步处理机制。
  2. 使用:https://blog.csdn.net/linmiansheng/article/details/40503791
  1. 创建一个Handler对象,并且实现其 handleMessage(Message msg) 方法
  2. 当创建好Handler对象之后,第二步就需要创建一个Message对象了,创建Message对象有两种方法:直接创建新对象new Message()利用Handler.obtainMessage()方法
  3. 当消息(Message)创建好了之后,我们就可以利用Handler的sendMessage来进行发送消息了,之后,这个消息就会被其handler所捕获,从而进行处理了。

四大组件:

https://blog.csdn.net/ican87/article/details/21874321

1、activity

一个Activity通常就是一个单独的屏幕(窗口)。Activity之间通过Intent进行通信android应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明,否则系统将不识别也不执行该Activity。

2、service

用于在后台完成用户指定的操作。service分为两种:started(启动):当应用程序组件(如activity)调用startService()方法启动服务时,服务处于started状态。bound(绑定):当应用程序组件调用bindService()方法绑定到服务时,服务处于bound状态。开发人员需要在应用程序配置文件中声明全部的service,使用<service></service>标签。Service通常位于后台运行,它一般不需要与用户交互,因此Service组件没有图形用户界面。Service组件需要继承Service基类。Service组件通常用于为其他组件提供后台服务或监控其他组件的运行状态。

(2)startService()与bindService()区别:

(a)started service(启动服务)是由其他组件调用startService()方法启动的,这导致服务的onStartCommand()方法被调用。当服务是started状态时,其生命周期与启动它的组件无关,并且可以在后台无限期运行,即使启动服务的组件已经被销毁。因此,服务需要在完成任务后调用stopSelf()方法停止,或者由其他组件调用stopService()方法停止。

(b)使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。

3content provider

android平台提供了Content Provider使一个应用程序的指定数据集提供给其他应用程序。其他应用可以通过ContentResolver类从该内容提供者中获取或存入数据。只有需要在多个应用程序间共享数据是才需要内容提供者。例如,通讯录数据被多个应用程序使用,且必须存储在一个内容提供者中。它的好处是统一数据访问方式。ContentProvider实现数据共享。ContentProvider用于保存和获取数据,并使其对所有应用程序可见。这是不同应用程序间共享数据的唯一方式,因为android没有提供所有应用共同访问的公共存储区。开发人员不会直接使用ContentProvider类的对象,大多数是通过ContentResolver对象实现对ContentProvider的操作。ContentProvider使用URI来唯一标识其数据集,这里的URI以content://作为前缀,表示该数据由ContentProvider来管理。

4broadcast receiver

(1)你的应用可以使用它对外部事件进行过滤,只对感兴趣的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个activity或serice来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力,例如闪动背灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。

(2)广播接收者的注册有两种方法,分别是程序动态注册和AndroidManifest文件中进行静态注册。

(3)动态注册广播接收器特点是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用。

android四大组件总结:

(1)4大组件的注册

4大基本组件都需要注册才能使用,每个Activity、service、Content Provider都需要在AndroidManifest文件中进行配置。AndroidManifest文件中未进行声明的activity、服务以及内容提供者将不为系统所见,从而也就不可用。而broadcast receiver广播接收者的注册分静态注册(在AndroidManifest文件中进行配置)和通过代码动态创建并以调用Context.registerReceiver()的方式注册至系统。需要注意的是在AndroidManifest文件中进行配置的广播接收者会随系统的启动而一直处于活跃状态,只要接收到感兴趣的广播就会触发(即使程序未运行)。

(2)4大组件的激活

内容提供者的激活:当接收到ContentResolver发出的请求后,内容提供者被激活。而其它三种组件activity、服务和广播接收器被一种叫做intent的异步消息所激活。

(3)4大组件的关闭

内容提供者仅在响应ContentResolver提出请求的时候激活。而一个广播接收器仅在响应广播信息的时候激活。所以,没有必要去显式的关闭这些组件。Activity关闭:可以通过调用它的finish()方法来关闭一个activity。服务关闭:对于通过startService()方法启动的服务要调用Context.stopService()方法关闭服务,使用bindService()方法启动的服务要调用Contex.unbindService()方法关闭服务。

(4)android中的任务(activity栈)

(a)任务其实就是activity的栈,它由一个或多个Activity组成,共同完成一个完整的用户体验。栈底的是启动整个任务的Activity,栈顶的是当前运行的用户可以交互的Activity,当一个activity启动另外一个的时候,新的activity就被压入栈,并成为当前运行的activity。而前一个activity仍保持在栈之中。当用户按下BACK键的时候,当前activity出栈,而前一个恢复为当前运行的activity。栈中保存的其实是对象,栈中的Activity永远不会重排,只会压入或弹出。

(b)任务中的所有activity是作为一个整体进行移动的。整个的任务(即activity栈)可以移到前台,或退至后台。

(c)Android系统是一个多任务(Multi-Task)的操作系统,可以在用手机听音乐的同时,也执行其他多个程序。每多执行一个应用程序,就会多耗费一些系统内存,当同时执行的程序过多,或是关闭的程序没有正确释放掉内存,系统就会觉得越来越慢,甚至不稳定。为了解决这个问题,Android引入了一个新的机制,即生命周期(Life Cycle)。

Listview的优化:

1、优化一:复用convertView

Android系统本身为我们考虑了ListView的优化问题,在复写的Adapter的类中,比较重要的两个方法是getCount()和getView()。界面上有多少个条显示,就会调用多少次的getView()方法;因此如果在每次调用的时候,如果不进行优化,每次都会使用View.inflate(….)的方法,都要将xml文件解析,并显示到界面上,这是非常消耗资源的:因为有新的内容产生就会有旧的内容销毁,所以,可以复用旧的内容。

优化:在getView()方法中,系统就为我们提供了一个复用view的历史缓存对象convertView,当显示第一屏的时候,每一个item都会新创建一个view对象,这些view都是可以被复用的;如果每次显示一个view都要创建一个,是非常耗费内存的;所以为了节约内存,可以在convertView不为null的时候,对其进行复用

 

2、优化二:缓存item条目的引用——ViewHolder

findViewById()这个方法是比较耗性能的操作,因为这个方法要找到指定的布局文件,进行不断地解析每个节点:从最顶端的节点进行一层一层的解析查询,找到后在一层一层的返回,如果在左边没找到,就会接着解析右边,并进行相应的查询,直到找到位置(如图)。因此可以对findViewById进行优化处理,需要注意的是:

特点:xml文件被解析的时候,只要被创建出来了,其孩子的id就不会改变了。根据这个特点,可以将孩子id存入到指定的集合中,每次就可以直接取出集合中对应的元素就可以了。

优化:在创建view对象的时候,减少布局文件转化成view对象的次数;即在创建view对象的时候,把所有孩子全部找到,并把孩子的引用给存起来

①定义存储控件引用的类ViewHolder

 

异步加载图片

异步加载图片:第三方API来加载图片,

  ImageLoader,Xutils里面的BitmapUtils

ImageLoader的异步加载图片,只需要传进去两个参数,第一个是图片url,第二个是ImageView控件,ImageLoader会自动给我们缓存图片的,如果之前加载过了是不会再次下载图片,直接加载本地缓存好的图片。

分批下载:

一般数据都是从数据库中获取的,实现分批(分页)加载数据,就需要在对应的DAO中有相应的分批(分页)获取数据的方法,如findPartDatas ()

1、准备数据:

在dao中添加分批加载数据的方法:findPartDatas ()

在适配数据的时候,先加载第一批的数据,需要加载第二批的时候,设置监听检测何时加载第二批

2、设置ListView的滚动监听器:setOnScrollListener(new OnScrollListener{….})

①、在监听器中有两个方法:滚动状态发生变化的方法(onScrollStateChanged)和listView被滚动时调用的方法(onScroll)

②、在滚动状态发生改变的方法中,有三种状态:

手指按下移动的状态: SCROLL_STATE_TOUCH_SCROLL: // 触摸滑动

惯性滚动(滑翔(flgin)状态): SCROLL_STATE_FLING: // 滑翔

静止状态: SCROLL_STATE_IDLE: // 静止

3、对不同的状态进行处理:

分批加载数据,只关心静止状态:关心最后一个可见的条目,如果最后一个可见条目就是数据适配器(集合)里的最后一个,此时可加载更多的数据。在每次加载的时候,计算出滚动的数量,当滚动的数量大于等于总数量的时候,可以提示用户无更多数据了。

图片本地缓存和内存软引用缓存

ImageDownloaderTask.java文件

(用于图片的下载和本地缓存。在要下载图片的位置调用此类的构造函数传入实现了下面文件3接口的对象,用于回调。

Get_ICON.java文件

(此文件实现图片的获取和软引用。在要获取图片的位置调用:getBitmapFromCache(String url)并传入图片对应的rul即可。

Fragment优化显示

Fragment+RadioGroup

在项目中需要进行Fragment的切换:

常用方法:Replace()来替换Fragment

缺点:replace每次都会重新调用fragment的onCreateView()方法,浪费时间。

优化方法:

  1. show()和hide()、add(),切换时hide(),add()另一个Fragment;再次切换时,只需hide()当前,show()另一个。这样就不会重复调用onCreateView函数了。缺点:界面多的时候会出现OOM
  2. 动态加载;

需要使用的时候,点击Fragment条目的时候动态切换了,调用switchFragment函数

  1. Tab页面,确切的说你还需要定义至少一个List<Fragment> fragmentList。将初始化完毕的所有Fragment加入fragmentlist,然后使用 add+attach+detattch方法进行管理,add负责添加,其他2个方法负责切换,这样效率特别好,防止了Fragment的叠加。

Android下的XML,JSON的解析(网络编程)

i.OKhttp
这里使用Square公司的OKHTTP框架,添加依赖:

 compile 'com.squareup.okhttp3:okhttp:3.6.0'

ii.需要联网权限:

  <uses-permission android:name="android.permission.INTERNET" />

iii.Apache http 服务器准备
下载:链接:http://pan.baidu.com/s/1qXZGqmg 密码:rj7x
下载得到msi文件,点击安装,安装教程很多,我不赘述了。
然后再浏览器输入:127.0.0.1
出现IT WORKS!说明服务器安装成功

XML

a)、任何的起始标签都必须有一个结束标签。

b)、可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如<百度百科词条/>。XML解析器会将其翻译成<百度百科词条></百度百科词条>。

c)、标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,例如这是一串百度百科中的样例字符串。这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。

d)、所有的特性都必须有值。

e)、所有的特性都必须在值的周围加上双引号。

android 配置文件,布局文件

解析XML主要有:PULL解析方法和SAX解析方法。

JSON

[{"id":"1","version":"1.2","name":"Tom"},
{"id":"2","version":"2.2","name":"Jack"},
{"id":"3","version":"1.6","name":"Tomson"}]
JSON 语法是 JavaScript 对象表示语法的子集。数据在键值对中
-数据由逗号分隔
-花括号保存对象
-方括号保存数组

解析JSon格式的数据通常有JSONObject和GSON两种方式:

1、JSONObject

2、GSON方式
GSON是一个开源库,使用它首先得添加依赖:

compile 'com.google.code.gson:gson:2.8.0'

数据存储和列表显示数据

将数据存储在本地数据库:

  1. 来一条数据就需要存一条数据
  2. 将数据库操作放在handle里面实现实时数据获取后插入数据库。
  3. 数据库需要列表显示

实现数据库操作SQLite

https://blog.csdn.net/qwm8777411/article/details/46048831

https://blog.csdn.net/qwm8777411/article/details/46048905

 

  1. SQLiteOpenHelper类的使用
  1. 创建一个持久化的数据库,通过继承SQLiteOpenHelper,然后再构造方法中调用

//传入定义好的数据库名和版本

super(context, DB_NAME, null, DB_VERSION);

  1. 覆写两个方法

当数据库文件创建的时候会调用onCreate() 可以在这个方法里面创建多张数据库表了

  @Override

public void onCreate(SQLiteDatabase db) {

//创建数据库表就需要使用sql语句

db.execSQL("create table "+TABLE_NAME+" ("+_ID+" integer primary key autoincrement," +_RATE+" text,"+_BREATH+" text,"+_STATE+" text,"+_TIME+" text);");

}

@Override

  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

//Update升级更新数据库可以在该方法里面删除/添加/修改数据库表

     db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);

      onCreate(db);

}

  1. SQLiteOpenHelper还提供了两个方法getWritableDatabase(),getReadableDatabase()用来得到SQLiteDatabase对象
  1. SQLiteDatabase

QLiteDatabase是一个基本数据库类,用于在Android中提供增删改查等基础操作。insert(),update(),delete();另外它还提供了execSQL()方法来直接执行SQL语句;

当我们需要插入或更新数据表时,需要使用ContentValues,ContentValues对象允许定义键值对,key指向数据表中的字段,value指向表记录的内容。

查询可以通过rawQuery()或者query()方法或者 SQLiteQueryBuilder()方法

  1. Cursor(光标)

一条查询返回一个Cursor对象, Cursor主要指向查询结果的一行,这样Android可以缓冲查询结果,而不用将所有数据全部加载到内存;

为了得到查询结果的数目,可以使用getCount();为了在查询的结果上移动,你可以使用moveToFirst(), moveToNext();

//传入一个列的列名 返回一个列的索引

    int columnIndex = cursor.getColumnIndex(DbOpenHelper._RATE);

    //传入一个列的索引 返回该列下 某一行的值

String rate = cursor.getString(columnIndex);

isAfterLast()则返回是否已经到达查询结果的末尾。

  1. 步骤总结:

Android常见的数据库操作按以下步骤做个总结:

  1. 为每一个表创建一个Model类,即对应数据类:
    1. Tips:为每一个表创建一个数据类是很好的建议,而且在表中增设id字段很有必要,因为很多数据库操作方法要依赖他。
  2. 实现DatabaseHandler类
    1. 继承自SQLiteOpenHelper类,实现构造函数(创建表)和覆写onCreate()、onUpgrade()方法
    2. 根据我们的需要封装CRUD方法(增删改查)
    3. 实现具体的CRUD方法
  3. 使用DatabaseHandler类,将数据绑定到界面,通过自定义adapter显示在adapterView(ListView..GridView等)上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值