android应用共享数据
⑴ Android图形系统(八)-app与SurfaceFlinger共享UI元数据过程
Android应用程序与SurfaceFlinger服务是运行在不同的进程中的,因此,它们采用Binder进程间通信机制来进行通信。
但是我们知道一个Android应用程序可能会有很多个窗口,而每一个窗口都有自己的UI元数据,因此,Android应用程序需要传递给SurfaceFlinger服务的UI元数据是相当可观的。在这种情况下,通过Binder来在Android应用程序与SurfaceFlinger服务之间传递UI元数据是不合适的,因此这里选择了Android系统的匿名共享内存的方案。在每一个Android应用程序与SurfaceFlinger服务之间的连接上加上一块用来传递UI元数据的匿名共享内存。而这块区域被包装为SharedClient。
在每一个SharedClient里面,有至多31个SharedBufferStack,那什么又是SharedBufferStack?
SharedBufferStack就是共享缓冲区堆栈,每一个SharedBufferStack与一个Surface一一对应,每一个Surface又对应一个窗口,那就是一个应用程序内部最多可创建31个窗口。SharedBufferStack 内部包含N个缓冲buffer, 开篇介绍的双缓冲(front buffer , back buffer) ,三缓冲(front buffer , back buffer, tripple buffer),有了它SurfaceFlinger服务就可以使用N个缓冲区技术来绘制UI了。
下面我们再来了解下SharedBufferStack的结构:
SharedBufferStack中分为空闲buffer和已使用的buffer。其中SharedBufferStack中的每一个已经使用了的缓冲区都对应有一个GraphicBuffer,用来描述真正的UI数据。
客户端一次申请GraphicBuffer且将UI元数据写入GraphicBuffer的流程:
当Android应用程序需要更新一个Surface的时候,它就会找到与它所对应的SharedBufferStack,并且从它的空闲缓冲区列表的尾部取出一个空闲的Buffer。我们假设这个取出来的空闲Buffer的编号为index。接下来Android应用程序就请求SurfaceFlinger服务为这个编号为index的Buffer分配一个图形缓冲区GraphicBuffer。SurfaceFlinger服务分配好图形缓冲区GraphicBuffer之后,会将它的编号设置为index,然后再将这个图形缓冲区GraphicBuffer返回给Android应用程序访问。Android应用程序得到了SurfaceFlinger服务返回的图形缓冲区GraphicBuffer之后,就在里面写入UI数据。写完之后,就将与它所对应的缓冲区,即编号为index的Buffer,插入到对应的SharedBufferStack的已经使用了的缓冲区列表的头部去。这一步完成了之后,Android应用程序就通知SurfaceFlinger服务去绘制那些保存在已经使用了的缓冲区所描述的图形缓冲区GraphicBuffer了。
那么我们也知道一个绘图表面,在SurfaceFlinger服务和Android应用程序中分别对应Layer对象和Surface对象,其中这两个对象在内部分别使用一个SharedBufferServer对象和一个SharedBufferClient对象来操作这个绘图表面的UI元数据缓冲堆栈。操作过程如下:
在Android应用程序这一侧,当它需要渲染一个Surface时,它就会首先找到对应的SharedBufferClient对象,然后再调用它的成员函数dequeue来请求分配一个UI元数据缓冲区。有了这个UI元数据缓冲区之后,Android应用程序再调用这个SharedBufferClient对象的成员函数setDirtyRegion、setCrop和setTransform来设置对应的Surface的裁剪区域、纹理坐标以及旋转方向。此外,Android应用程序还会请求SurfaceFlinger服务为这个Surface分配一个图形缓冲区,以便可以往这个图形缓冲区写入实际的UI数据。最后,Android应用程序就可以调用这个SharedBufferClient对象的成员函数queue把前面已经准备好了的UI元数据缓冲区加入到它所描述的一个UI元数据缓冲区堆栈的待渲染队列中,以便SurfaceFlinger服务可以在合适的时候对它进行渲染。当SurfaceFlinger服务需要渲染一个Surface的时候,它就会找到对应的一个SharedBufferServer对象,然后调用它的成员函数getQueueCount来检查它所描述的一个UI元数据缓冲区堆栈的待渲染队列的大小。如果这个大小大于0,那么SurfaceFlinger服务就会继续调用它的成员函数retireAndLock来取出队列中的第一个UI元数据缓冲区,以及调用它的成员函数getDirtyRegion、getCrop和getTransform来获得要渲染的Surface的裁剪区域、纹理坐标和旋转方向。最后,SurfaceFlinger服务就可以结合这些信息来将保存这个Surface的图形缓冲区中的UI数据渲染在显示屏中。
另外想深入了解BufferQueue的生产者消费者模型,详细可以阅读下如下这篇博文,感觉还不错: https://blog.csdn.net/stn_lcd/article/details/73801313
参考:
https://blog.csdn.net/Luoshengyang/article/details/7867340
⑵ 如何android多Activity间共享数据
1、在某个Activity中声明一个公共的static变量把共享数据作为静态变量,但是这样会增加activity之间的耦合度,不是很好。
2、把共享数据作为放在Applicaiton中。定义一个MyApplication继承于Application,将MyApplication配置到清单文件中作为程序启动的ApplicationContext,设置Application的name属性即可。
可以按以下步骤进行:
Android应用的数据库一般都是私有的,其他应用无法访问,那么怎么在手机已root的前提下,在自己的应用中读取指定应用中的数据信息呢,现提供一种思路。
以uc浏览器历史浏览记录为例:
一:对手机进行root。
某些厂家的Android设备是支持在系统设置中一键root的,如魅族手机。更通用的情况下一般是用第三方软件进行root,如KingRoot。
二:在手机上安装RootExplorer。
RootExplorer是在Android上使用很方便的文件浏览器,借用它,我们可以找到uc浏览器的历史记录数据库所在为data/data/com.UCMobile/databases/history/history。
三:将数据库文件复制到sd卡指定目录。
四:从sd卡数据库文件中读取数据。
五:将数据加载到Recyclerview中展示。
至此,我们已经实现了在自己应用中读取其他应用数据库数据的一个完整过程,诚然这种方式存在许多局限性,但不失为解决方案的一种。
⑷ 如何android多Activity间共享数据
你好,方法如下
方法1:在某个Activity中声明一个公共的static变量把共享数据作为静态变量
public class OneActivity extends Activity {
public static Data data = null;//声明的变量
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
data = new Data();
}
}public class TwoActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Data data = OneActivity.data;
}
但是这样会增加activity之间的耦合度,不是很好
方法二:把共享数据作为放在Applicaiton中
定义一个MyApplication继承于Application
public class MyApplication extends Application{
private Data data;
@Override
public void onCreate() {
super.onCreate();
data = new Data();
}
public Data getData(){
return data;
}
public void setData(Data data){
this.data = data;
}
}
将MyApplication配置到清单文件中作为程序启动的ApplicationContext
设置Application的name属性即可
在Activity中获取数据
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyApplication application = (MyApplication) getApplication();
Data data = application.getData();
}
}
⑸ 如何在不同的android应用之间共享数据
在本应用中保存数据。
java">//实例化SharedPreferences对象(第一步)
=getSharedPreferences("test",Activity.MODE_WORLD_READABLE);
//MODE_WORLD_READABLE:表示当前文件可以被其他应用读取
//MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。
//实例化SharedPreferences.Editor对象(第二步)
SharedPreferences.Editoreditor=mySharedPreferences.edit();
//用putString的方法保存数据
editor.putString("name","我是name的数据");
editor.putString("name2","我是name2的数据");
//提交当前数据,提交以后数据才真正保存
editor.commit()
2.在其他应用中获取数据
=getSharedPreferences("test",Activity.MODE_WORLD_READABLE);
//通过名称name获取存储的值,如果这个那么没有存过值,就显示第二个参数的默认值。
mySharedPreferences.getString("name","如果name不存在那么显示我这个默认值");
mySharedPreferences.getString("name2","如果name2不存在那么显示我这个默认值");