安卓组件化数据存储
Ⅰ 安卓MVVM模式以及数据的请求与缓存
MVVM模式就相当于把ViewModel改名为Presener,其他基本相同。在ViewModel中处理数据逻辑,调用数据请求。但它和MVP的区别是可以双向绑定,ViewModel中数据的改变可以直接反应在View上,而View的修改也可以影响ViewModel,这样就省去Presenter和View之间的大量的调用接口。
谷歌官方提供了一个ViewModel类。这个类主要用来保存View的数据,一般在Activity的onCreate()方法中初始化ViewModel,但如果第二次调用onCreate(),那获取到的ViewModel依然是第一次生成的那个实例,这就保证了数据的连贯。一般使用的场景为当屏幕旋转时,Activity会重新调用onCreate()方法,但这时ViewModel依然能保存之前的数据。但Activity完全finish时,ViewModel才会被清空。
使用ViewModel还有其他好处,比如方便同一个Activity中不同的Fragment直接的通信,可以避免内存泄漏等等。
以下是ViewModel的基本使用方法,来自 官网 :
ViewModel一般和LiveData一起用。LiveData中的数据发生改变时,能发送通知给观察者,观察者就能修改相应的View。这也使得MVVM模式获取数据时可以直接返回一个结果,而不用等网络请求数据成功后再通过回调返回数据,因为在回调中修改数据之后,LiveData会自动通知大家这个数据被修改了。
除此之外谷歌还提供了其他的架构组件,包括Lifecycle和Room等,可以查看官网的介绍。
Ⅱ 如何在android中利用shared preferences存储和读取数据
1、任务目标
(1)掌握Android中SharedPreferences的使用方法。
2、任务陈述
(1)运行后,显示如下界面,可以写入和读取SharedPreferences中的数据:
3、任务实施及所涉及知识技能讲解
第一步:新建一个Android工程,命名为SharedPreferencesWrite。
第二步:在layout下添加一个使用线性布局的布局文件,命名为:main.xml。
布局文件源代码:
http://www.worlc.com/blog2012.aspx?bid=19403636
第三步:在CopySharedPreferencesTest.java下声明如下变量,并导入导入相关包(如何使用SharedPreferences存储和读取数据):
[java] view plain
SharedPreferences preferences;
Editor editor;
第四步:在onCreate方法中修改如下代码:
[java] view plain
setContentView(R.layout.main);
第五步:在onCreate方法中实例化前面声明的两个对象,代码如下:
[java] view plain
preferences = getSharedPreferences("crazyit", MODE_WORLD_READABLE);
editor = preferences.edit();
第六步:在onCreate方法中获取两个按钮,代码如下:
[java] view plain
Button read = (Button) findViewById(R.id.read);
Button write = (Button) findViewById(R.id.write);
第七步:在onCreate方法中为两个按钮添加监听器,代码如下:
[java] view plain
write.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View arg0)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 "
+ "hh:mm:ss");
// 存入当前时间
editor.putString("time", sdf.format(new Date()));
// 存入一个随机数
editor.putInt("random", (int) (Math.random() * 100));
// 提交所有存入的数据
editor.commit();
}
});
read.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View arg0)
{
//读取字符串数据
String time = preferences.getString("time", null);
//读取int类型的数据
int randNum = preferences.getInt("random", 0);
String result = time == null ? "您暂时还未写入数据": "写入时间为:" + time + "\n上次生成的随机数为:" + randNum;
//使用Toast提示信息
Toast.makeText(SharedPreferencesTest.this ,
result , 5000).show();
}
});
第七步:点击运行程序,程序源代码如下:http://www.worlc.com/blog2012.aspx?bid=19403601
课堂练习:创建一个记录应用程序使用次数的程序,当用户第一次启动应用程序时,系统创建SharedPrefererences,来记录使用次数。用户以后启动应用程序时,系统先读取SharedPrefererences中记录的使用次数,然后将使用次数加1。
程序源代码如下:
http://www.worlc.com/blog2012.aspx?bid=19403695
Ⅲ Android MMKV - 性能强悍的存储工具(腾讯出品)
MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今在微信上使用,其性能和稳定性经过了时间的验证.
微信作为一个即时通讯项目,需要记录数据比较多.需要频繁的操作记录的数据,需要一个性能强悍的存储组件,他们考察了 SharedPreferences、NSUserDefaults、sqlite 等常见组件,发现都没能满足如此苛刻的性能要求。考虑到这个防 crash 方案最主要的诉求还是实时写入,而 mmap 内存映射文件刚好满足这种需求,就尝试通过它来实现一套 key-value 组件。MMKV 就应运而生了.
重复读写操作 1k 次 MMKV 和 SharedPreferences、SQLite 性能对比( 机型:华为 Mate 20 Pro,版本:Android 10)
注意:
一些 Android 设备(API level 19)在安装/更新 APK 时可能出错, 导致 libmmkv.so 找不到。然后就会遇到 java.lang.UnsatisfiedLinkError 之类的 crash。有个开源库 ReLinker 专门解决这个问题,你可以用它来加载 MMKV
MMKV 是腾讯出品的基于mmap内存映射文件技术的一种数据存储的组件,相对于SharedPreferences SQlite 兼容性更好,存读取速度更快.支持常规的各种数据类型.
来都来了,点个赞再走吧!!!
1.MMKV 文档
2.源码地址
Ⅳ Android 轻量级存储方案(SharedPreferences、MMKV、Jetpack DataStore)
SharedPreferences使用:
SharedPreferencesImpl#EditorImpl.java 中最终执行了apply()函数:
创建一个awaitCommit的Runnable任务并将其加入到QueuedWork中,该任务内部直接调用了CountDownLatch.await()方法,即直接在UI线程执行等待操作,那么我们看QueuedWork中何时执行这个任务。
QueuedWork.java:
waitToFinish()方法会尝试从Runnable任务队列中取任务,如果有的话直接取出并执行,我们看看哪里调用了waitToFinish():
ActivityThread.java
可以看到在ActivityThread中handleStopActivity、handleStopService方法中都会调用waitToFinish()方法,即在Activity的onStop()中、Service的onStop()中都会先同步等待写入任务完成才会继续执行。
所以apply()虽然是异步写入磁盘,但是如果此时执行到Activity/Service的onStop(),依然可能会阻塞UI线程导致ANR。
Jetpack DataStore 是一种改进的数据存储解决方案,允许您使用 协议缓冲区 存储键值对或类型化对象。
DataStore 使用 Kotlin 协程和 Flow 以异步、一致的事务方式存储数据。并且可以对SP数据进行迁移,旨在取代SP。如果正在使用 SharedPreferences 存储数据,请考虑迁移到 DataStore。
Jetpack DataStore 有两种实现方式:
1.添加依赖项:
2.构建Preferences DataStore:
当我们构建后,会在 /data/data/<package name>/files/ 下创建名为 preferences_dataStore 的文件如下:
1.构建Preferences DataStore
2.存储的实体类:
3.数据存储/获取:
Activity中:
ViewModel中:
Repository类中:
SP迁移至Preferences DataStore
如果想将项目的SP进行迁移,只需要在Preferences DataStore在构建时配置参数3,如下:
这样构建完成时,SP中的内容也会迁移到Preferences DataStore中了,注意迁移是一次性的,即执行迁移后,SP文件会被删除.
MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。
1.添加依赖:
2.Application的onCreate方法中初始化
3.数据存储/获取:
github地址: https://github.com/HuiZaierr/Android_Store
Ⅳ Android 怎样在应用程序中向文件里写入数据
Android 怎样在应用程序中向文件里写入数据?在AndroidManifest.xml中添加, <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />,解决!
另外了解一下android的数据存储方式:文件流的读取,SQLite,Content Provider以及Preference.。 注:resource和assets中的文件用户方面是只可以读取不能够进行写的操作的。
Content Provider作为程序之间唯一共享数据途径,用在这里不是很合适。所以,
第一种方式,使用FileInputStream,FileOutputStreami类实现文件I/O操作,直接往手机中存储数据。
第二种方式,使用SQLite,通过SQLiteDatabase类中方法操作数据。
第三种方式,Preference用于存储简单数据类型的数据,一些设置信息的保存。个人认为用在这里最合适。 它利用键值对存储的。例:
存储:SharedPreferences.Editor editor =sp.edit();
editor.putString(KEY_TEXT,"yonghu");
editor.commit();
获取 :sp =getPreferences(MODE_PRIVATE);String result =sp.getString(KEY_TEXT,null)
Android保存数据几种常用方法解析
它应用于手机中能够帮助我们实现许多需求。比如今天为大家介绍的Android保存数据,就是其中一个比较重要的操作技巧。Android组件相关概念总结Android传值方法细讲Android横竖屏切换正确实现方式分享Android开发环境相关配置概览Android NDK具体作用讲解对于我们所熟悉的大部分软件都有一个比较典型的特点,应用现有的数据根据不同的需求来得到相应的结果。例如,我们最常用的Officeword、Excel、PowerPoint等办公软件,它们都是帮助我们完成某种特定的需求,同时由其所产生的数据或者文档又可以被其它软件所读取和做进一步的优化等等,在这个层面上可以看成是这些软件通过相同的文件标准来共享数据。但是对于Android最大的不同点在于,其平台上的应用软件所存储的数据或者文件是私有,仅仅可以通过它自身才可以访问其所包含的数据资源。那么基于这样的限制,该如何在Android平台上实现不同程序间的数据共享呢?答案非常简单 – 应用ContentProviders,这是建立在Android平台上用于定义统一的数据标准。Android提供了针对不同数据类型的ContentProviders来满足各种需要。例如:Image、Audio、Video和通讯录信息类等。阅读下边的文档之前,最好先熟悉Content Providers的概念。有了上边所提到Content Providers,接下来就要处理在共享文件过程中的存储环节了,这里有四种方法分别适用于不同情况的需求。它们都各自有相应的优缺点,所以当开发者决定选择应用哪种方法之前,先要考虑当前所操作的情况是否适合于所选择的方法。Preferences Files Databases Network 接下来将依次介绍上诉四个Android保存数据方法:Preferences从其保存数据的结构来分析,这是一个相对较轻量级的存储数据的方法。类似于我们常用的ini文件保存软件初始化设置,同样在Android平台常用于存储较简单的参数设置。例如,可以通过它保存上一次用户所作的修改或者自定义参数设定,当再次启动程序后依然保持原有的设置。通过Context.getSharedPreferences()方法来读写数值,这个方法通过设置name来使得同一个程序内的其它模块共享数据。如果不需要与其它模块共享数据,可以使用Activity.getPreferences()方法保持数据私有。需要着重强调一点,无法直接在多个程序间共享Preferences数据(不包括使用Content Providers)。通过一个实例来了解实际使用方法:import android.app.Activity; import android.content.SharedPreferences; public class Calc extends Activity { public static final String PREFS_NAME = "MyPrefsFile"; . . . . Override protected void onCreate(Bundle state){ super.onCreate(state); . . . . // Restore preferences SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); boolean silent = settings.getBoolean("silentMode", false); setSilent(silent); } @Override protected void onStop(){ super.onStop(); // Save user preferences. We need an Editor object to // make changes. All objects are from android.context.Context SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); editor.putBoolean("silentMode", mSilentMode); // Don't forget to commit your edits!!! editor.commit(); } } Files从这是第二种方法,可以在设备本身的存储设备或者外接的存储设备中创建用于保存数据的文件。同样在默认的状态下,文件是不能在不同的程序间共享。写文件:调用Context.openFileOutput()方法根据指定的路径和文件名来创建文件,这个方法会返回一个FileOutputStream对象。读取文件:调用Context.openFileInput()方法通过制定的路径和文件名来返回一个标准的Java FileInputStream对象。
(注意:在其它程序中将无法应用相同的路径和文件名来操作文件)另外编译程序之前,在res/raw/tempFile中建立一个static文件,这样可以在程序中通过Resources.openRawResource (R.raw.myDataFile)方法同样返回一个InputStream对象,直接读取文件内容。Databases在Android API中包括了应用SQLite databases的接口,每个程序所创建的数据库都是私有的,换句话说,程序间无法相互访问对方的数据库。在程序中创建SQLiteDatabase对象,其中包含了大部分与database交互的方法,例如:读取数据或者管理当前数据。可以应用SQLiteDatabase和其subClassSQLiteOpenHelper的create()方法来创建新的数据库。对于SQLitedatabase而言,其强大和方便的功能为Android提供了强有力的存储功能。特别是存储一些复杂的数据结构,例如:Android特别为通讯录创建了特有的数据类型,其中包含了非常多的子集而且涵盖了大部分的数据类型 “First Name” “Last Name” “PhoneNumber”和“Photo”等。Android可以通过Sqlite3 database tool来查看指定数据库中表的内容,直接运行SQL命令来快速便捷的直接操作SQLite database。
Ⅵ Android之ContentProvider使用
ContentProvider是Android四大组件之一,其本质上是一个标准化的数据管道,它屏蔽了底层的数据管理和服务等细节,以标准化的方式在Android 应用间共享数据。用户可以灵活实现ContentProvider所封装的数据存储以及增删改查等,所有的ContentProvider 必须实现一个对外统一的接口(URI)。
使用的时候需要在androidmanifest.xml文件中注册provider。
在androidmanifest.xml中注册provider需要以下3个属性:
Ⅶ Android 下的 WebView 中数据如何保存
1、Android中的WebView控件当加载html时候,会在data/应用package下生成database与cache两个文件夹如下图如示:
Url记录是保存在webviewCache.db里,而url的内容是保存在webviewCache文件夹下。
WebView中存在着两种缓存:网页数据缓存(存储打开过的页面及资源)、H5缓存(即AppCache)。
2、缓存构成
/data/data/package_name/cache/
/data/data/package_name/database/webview.db
/data/data/package_name/database/webviewCache.db
webview 会将浏览过的网页url以及网页文件(css、图片、js等)保存到数据库表中。
缓存模式(5种)
LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
LOAD_DEFAULT: 根据cache-control决定是否从网络上取数据。
LOAD_CACHE_NORMAL: API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式
LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
Ⅷ android怎样缓存数据面试题
共有七个周期函数,按顺序分别是: onCreate(), onStart(), onRestart(), onResume(), onPause(),onStop(), onDestroy()。
onCreate(): 创建Activity时调用,设置在该方法中,还以Bundle的形式提供对以前存储的任何状态的访问。
onStart(): Activity变为在屏幕上对用户可见时调用。
onResume(): Activity开始与用户交互时调用(无论是启动还是重新启动一个活动,该方法总是被调用。
onPause(): Activity被暂停或收回cpu和其他资源时调用,该方法用户保护活动状态的,也是保护现场。
onStop(): Activity被停止并转为不可见阶段及后续的生命周期事件时调用。
onRestart(): Activity被重新启动时调用。该活动仍然在栈中,而不是启动新的Activity。
1、完整生命周期: 即从一个Activity从出现到消失,对应的周期方法是从onCreate()到onDestroy()。
2、可见生命周期: 当Activity处于可以用户看见的状态,但不一定能与用户交互时,将多次执行从onStart()到onStop()。
3、前景生命周期: 当Activity处于Activity栈最顶端,能够与其他用户进行交互时,将多次执行从onResume()到onPause()。
2. 两个Activity之间跳转时必然会执行的是哪几个方法。
答: 两个Activity之间跳转必然会执行的是下面几个方法。
onCreate()//在Activity生命周期开始时调用。
onRestoreInstanceState()//用来恢复UI状态。
onRestart()//当Activity重新启动时调用。
onStart()//当Activity对用户即将可见时调用。
onResume()//当Activity与用户交互时,绘制界面。
onSaveInstanceState()//即将移出栈顶保留UI状态时调用。
onPause()//暂停当前活动Activity,提交持久数据的改变,停止动画或其他占用GPU资源的东西,由于下一个Activity在这个方法返回之前不会resume,所以这个方法的代码执行要快。
onStop()//Activity不再可见时调用。
onDestroy()//Activity销毁栈时被调用的最后一个方法。
3. 横竖屏切换时候Activity的生命周期。
答:
1、不设置Activity的android: configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次。
2、设置Activity的android: configChanges=“orientation”时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次。
3、设置Activity的android: configChanges=“orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行onConfiguration方法
4. 如何将一个Activity设置成窗口的样式。
答: 第一种方法,在styles.xml文件中,可以新建如下的类似Dialog的style。
<style name=“Theme.FloatActivity” parent=“android:style/Theme.Dialog”> </style>。
第二种方法,在AndroidManifest.xml中在需要显示为窗口的Activity中添加如下属性: android: theme=“@style/Theme.FloatActivity”即可。也可以直接添加对应需要展示为Dialog style的Activity的android: theme属性为android: theme=“@ android: style/Theme.Dialog”。
5. 两个Activity之间怎么传递数据?
答: 可以在Intent对象中利用Extra来传递存储数据。
在Intent的对象请求中,使用putExtra(“键值对的名字”,”键值对的值”);在另外一个Activity中将Intent中的请求数据取出来:
Intent intent = getIntent();
String value = intent.getStringExtra(“testIntent”);
6. 怎么让在启动一个Activity是就启动一个service?
答: 首先定义好一个service,然后在Activity的onCreate里面进行连接并bindservice或者直接startService。
7. Activity怎么和service绑定,怎么在activity中启动自己对应的service?
答:
1、activity能进行绑定得益于Serviece的接口。为了支持Service的绑定,实现onBind方法。
2、Service和Activity的连接可以用ServiceConnection来实现。需要实现一个新的ServiceConnection,重现onServiceConnected和OnServiceDisconnected方法,一旦连接建立,就能得到Service实例的引用。
3、执行绑定,调用bindService方法,传入一个选择了要绑定的Service的Intent(显示或隐式)和一个你实现了的ServiceConnection的实例
8.什么是Service以及描述下它的生命周期。Service有哪些启动方法,有什么区别,怎样停用Service?
答: Android Service是运行在后台的代码,不能与用户交互,可以运行在自己的进程,也可以运行在其他应用程序进程的上下文里。需要通过某一个Activity或者Context对象来调用。Service有两个启动方法,分别是Context.startService()和Context.bindService()。如果在Service执行耗时的操作需要启动一个新线程来执行。
Android Service只继承了onCreate(), onStart(),onDestroy()三个方法,当我们第一次启动Service时,先后调用onCreate(), onStart()这两个方法,当停止Service时,则执行onDestroy()方法时。如果Service已经启动了,当我们再次启动Service时,不会再执行onCreate()方法,而是直接执行onStart()方法。
9. 什么时候使用Service?
答: 比如播放多媒体的时候,用户启动了其他Activity,这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你的地理信息位置的改变等等。
10. 请描述一下Intent 和 Intent Filter。
答: Intent在Android中被翻译为”意图”,他是三种应用程序基本组件-Activity,Service和broadcast receiver之间相互激活的手段。在调用Intent名称时使用ComponentName也就是类的全名时为显示调用。这种方式一般用于应用程序的内部调用,因为你不一定会知道别人写的类的全名。而Intent Filter是指意图过滤,不出现在代码中,而是出现在android Manifest文件中,以<intent-filter>的形式。(有一个例外是broadcast receiver的intent
filter是使用Context.registerReceiver()来动态设定的,其中intent filter也是在代码中创建的)
一个intent有action,data,category等字段。一个隐式intent为了能够被某个intent filter接收,必须通过3个测试,一个intent为了被某个组件接收,则必须通过它所有的intent filter中的一个。
11. Intent传递数据时,可以传递哪些类型数据?
答: intent间传送数据一般有两种常用的方法: 1、extra 2、data。
extra可以用Intent.putExtra放入数据。新启动的Activity可用Intent.getExtras取出Bundle,然后用Bundles.getLong,getInt,getBoolean,getString等函数来取放进去的值。
Data则是传输url。url可以是指我们熟悉的http,ftp等网络地址,也可以指content来指向ContentProvider提供的资源。Intent.setData可以放入数据,Intent.getData可以取出数据。
12. 说说Activity,Intent,Service是什么关系 ?
答: 一个Activity通常是一个单独的屏幕,每一个Activity都被实现为一个单独的类,这些类都是从Activity基类中继承而来的。Activity类会显示由视图控件组成的用户接口,并对视图控件的事件做出响应。
Intent的调用是用来进行屏幕之间的切换。Intent描述应用想要做什么。Intent数据结构中两个最重要的部分是动作和动作对应的数据,一个动作对应一个动作数据。
Service是运行在后台的代码,不能与用户交互,可以运行在自己的进程里,也可以运行在其他应用程序进程的上下文里。需要一个Activity或者其他Context对象来调用。
Activity跳转Activity,Activity启动Service,Service打开Activity都需要Intent表明意图,以及传递参数,Intent是这些组件间信号传递的承载着。
13. 请描述一下BroadcastReceiver。
答: Broadcast Receiver用于接收并处理广播通知(broadcast announcements)。多数的广播是系统发起的,如地域变换、电量不足、来电短信等。程序也可以播放一个广播。程序可以有任意数量的broadcast receivers来响应它觉得重要的通知。Broadcast receiver可以通过多种方式通知用户: 启动activity、使用NotificationManager、开启背景灯、振动设备、播放声音等,最典型的是在状态栏显示一个图标,这样用户就可以点它打开看通知内容。通常我们的某个应用或系统本身在某些事件(电池电量不足、来电短信)来临时会广播一个Intent出去,我们利用注册一个broadcast
receiver来监听这些Intent并获取Intent中的数据。
14. 在manifest和代码中如何注册和使用 broadcast receiver 。
答: 在android的manifest中注册
<receiver android: name =“Receiver1”>
<intent-filter>
<!----和Intent中的action对应--->
<actionandroid: name=“com.forrest.action.mybroadcast”/>
</intent-filter>
</receiver>
在代码中注册
1、 IntentFilter filter = new IntentFilter(“com.forrest.action.mybroadcast”);//和广播中Intent的action对应;
2、 MyBroadcastReceiver br= new MyBroadcastReceiver();
3、 registerReceiver(br, filter);
15. 请介绍下ContentProvider是如何实现数据共享的。
答: 一个程序可以通过实现一个Content provider的抽象接口将自己的数据完全暴露出去,而且Content provider是以类似数据库中的表的方式将自己的数据暴露。Content provider存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。
要想使应用程序的数据公开化,可通过2种方法:创建一个数据自己的Content Provider或者将你的数据添加到一个已经存在的Content Provider中,前提是有相同数据类型并且有写入Content Provider的权限,Android提供了Content Resolverr,外界的程序可以通过Content Resolver接口访问Content Provider提供的数据。
16. 请介绍下Android的数据存储方式。
答: Android提供了5中存储数据的方式,分别是以下几种
1、使用Shared Preferences存储数据,用来存储key-value,pairs格式的数据,它是一个轻量级的键值存储机制,只可以存储基本数据类型。
2、使用文件存储数据,通过FileInputStream和FileOutputStream对文件进行操作。在Android中,文件是一个应用程序私有的,一个应用程序无法读写其他应用程序的文件。
3、使用SQLite数据库存储数据,Android提供的一个标准数据库,支持SQL语句。
4、使用Content Provider存储数据,是所有应用程序之间数据存储和检索的一个桥梁,它的作用就是使得各个应用程序之间实现数据共享。它是一个特殊的存储数据的类型,它提供了一套标准的接口用来获取数据,操作数据。系统也提供了音频、视频、图像和个人信息等几个常用的Content Provider。如果你想公开自己的私有数据,可以创建自己的Content Provider类,或者当你对这些数据拥有控制写入的权限时,将这些数据添加到Content Provider中实现共享。外部访问通过Content Resolver去访问并操作这些被暴露的数据。
5、使用网络存储数据
17. 请介绍下Android中常用的五种布局。
答: 最常用的布局方式为Absolute Layout、Relative Layout、Linear Layout、FrameLayout、TableLayout。其中Linear Layout和Relative Layout是最常用的方式,他们可以通过在xml配置文件或者代码中进行布局。
1、Frame Layout是最简单的布局方式,放置的控件都只能罗列到左上角,控件会有重叠,不能进行复杂的布局。
2、Linear Layout可以通过orientation属性设置线性排列的方向是垂直还是纵向的,每行或每列只有一个元素,可以进行复杂的布局。
3、Absolute Layout可以让子元素指定准确的x、y坐标值,并显示在屏幕上。Absolute Layout没有页边框,允许元素之间相互重叠。它是绝对坐标,所以在实际中不提倡使用。
4、Relative Layout允许子元素制定他们相对于其他元素或父元素的位置(通过ID制定)。因此,你可以以右对齐,或上下,或置于屏幕中央的形式来排列两个元素。元素按顺序排列,因此如果第一个元素在屏幕的中央,那么相对于这个元素的其他元素将以屏幕中央的相对位置来排列。这个是相对于Absolute Layout的,采用相对坐标,所以在实际中比较常用。
5、Table Layout将以子元素的位置分配到行或列。一个Table Layout由许多的Table Row组成,每个Table Row都会定义一个row。Table Layout容器不会显示row、column或者cell的边线框。每个row拥有0个或多个的cell; 和html中的table差不多。在实际中也经常使用。
18. 谈谈UI中, Padding和Margin有什么区别?
答: Padding是控件的内容相对控件的边缘的边距,而Margin是控件边缘相对于其他控件的边距。如下图所示:
19. android本身的一些限制,比如apk包大小限制,读取大文件时的时间限。
答:apk包大小限制不好说,有的apk为100M,还是能装到手机上。一般的apk大小为5~10M左右。读取大文件的时间应该是在main线程里面,时间限制为5秒左右。
20. ListView如何提高其效率?
答:1、使用分页加载,不要一次性加载所有数据。
2、复用convertView。在getItemView中,判断converView是否为空,如果不为空,可复用。
3、异步加载图片。Item中如果包含有webimage,那么最好异步加载。
4、快速滑动时,不显示图片。当快速滑动列表(SCROLL_STATE_FLING),item中的图片或获取需要消耗资源的view,可以不显示出来;而处于其他两种状态(SCROLL_STATE_IDLE和SCROLL_STATE_TOUCH_SCROLL),则将那些view显示出来
Ⅸ android 组件间、进程间数据传输和限制
1、Bunder 传递对象为什么需要序列化?
1》因为 bundle 传递数据时只支持基本数据类型,所以在传递对象时需要序列化转
换成可存储或可传输的本质状态(字节流)。序列化后的对象可以在网络、IPC
(比如启动另一个进程的 Activity、Service 和 Reciver)之间进行传输,也可以 存储到本地。
2》序列化,表示将一个对象转换成可存储或可传输的状态。序列化的原因基本三种 情况:
1.永久性保存对象,保存对象的字节序列到本地文件中; 2.对象在网络中传递;
3.对象在 IPC 间传递。
2、序列化Serializable 和Parcelable 的区别
Serializable(Java 自带):
1》Serializable 是序列化的意思,表示将一个对象转换成存储或可传输的状态。序列化后的对象可以在网络上进传输,也可以存储到本地。
2》Serializable 会使用反射,序列化和反序列化过程需要大量 I/O 操作。
Parcelable(android 专用):
1》除了 Serializable 之外,使用 Parcelable 也可以实现相同的效果,不过不同于将 对象进行序列化,Parcelable 方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是 Intent 所支持的数据类型,这也就实现传递对象的功能 了。
2》Parcelable 自已实现封送和解封(marshalled &unmarshalled)操作不需要用反 射,数据也存放在 Native 内存中,效率要快很多。
两者最大的区别在于 存储媒介的不同,Serializable 使用 I/O 读写存储在硬盘 上,而 Parcelable 是直接 在内存中读写。很明显,内存的读写速度通常大于 IO 读写,所以在 Android 中传递数据优先选择 Parcelable。
3、bundle传输的数据是否有限制,是多少,为什么要限制?
1》Intent 在传递数据时是有大小限制的,大约限制在 1MB 之内,你用 Intent 传递 数据,实际上走的是跨进程通信(IPC),跨进程通信需要把数据从内核 到进程中,每一个进程有一个接收内核数据的缓冲区,默认是 1M;如果一次传 递的数据超过限制,就会出现异常。
2》不同厂商表现不一样有可能是厂商修改了此限制的大小,也可能同样的对象在不 同的机器上大小不一样。
3》传递大数据,不应该用 Intent;考虑使用 ContentProvider 或者直接匿名共享内 存。简单情况下可以考虑分段传输。
4、匿名共享内存(https://www.jianshu.com/p/d9bc9c668ba6)
Ⅹ android 怎么做数据缓存
二级缓存工作机制
所谓二级缓存实际上并不复杂,当Android端需要获得数据时比如获取网络中的图片,我们首先从内存中查找(按键查找),内存中没有的再从磁盘文件或sqlite中去查找,若磁盘中也没有才通过网络获取;当获得来自网络的数据,就以key-value对的方式先缓存到内存(一级缓存),同时缓存到文件或sqlite中(二级缓存)。注意:内存缓存会造成堆内存泄露,所有一级缓存通常要严格控制缓存的大小,一般控制在系统内存的1/4。
理解了二级缓存大家可能会有个问题网络中的数据是变化的,数据一旦放入缓存中,再取该数据就是从缓存中获得,这样岂不是不能体现数据的变化?我们在缓存数据时会设置有效时间,比如说30分钟,若超过这个时间数据就失效并释放空间,然后重新请求网络中的数据。有的童鞋就问30分钟内咋办?那好吧,我也没招了,只有下拉刷新了, 实际上这不是问题。
二级缓存的实现
如何实现二级缓存,有很多技术方案,在这里我们使用 ASimpleCache框架来给大家演示一下,通过名字就可以看出它是很容易实现的。
1、ACache介绍
ASimpleCache是一个轻量级的开源cache框架,实际上就是一个叫ACache的java类。已经在商业项目中使用,运行效果不错。
2、ACache使用
我们先做一个实现数据缓存的案例,然后再归纳一下主要的方法
编写NewsListActivity主要代码如下:
创建ACache组件
ACache acache=ACache.get(context)
或
ACache acache=ACache.get(context,max_size,max_count)
参数说明:
max_size:设置限制缓存大小,默认为50M
max_count:设置缓存数据的数量,默认不限制
设置缓存数据
acache.put(key,data,time)或acache.put(key,data)
将数据同时上存入一级缓存(内存Map)和二级缓存(文件)中
参数说明:
Key:为存入缓存的数据设置唯一标识,取数据时就根据key来获得的
Data:要存入的数据,acache支持的数据类型如图所示:
有String、可序列化的对象、字节数组、Drawable等Time:设置缓存数据的有效时间,单位秒
从缓存中取数据
提供一系列getAsXXX()方法,如图所示。
根据不同存入数据,调用不同的方法取数据