首页 文章 精选 留言 我的

精选列表

搜索[android jetpack],共10000篇文章
优秀的个人博客,低调大师

Android——volatile

作用: (1)每次访问该关键词修饰的变量都必须在内存上访问,而不是读取寄存器中的副本; (2)防止某些变量被其他线程修改,而使用该变量的其他线程不能访问该变量的最新值; (3)实现简单的同步锁的功能; 使用条件: 对变量的写操作不依赖于当前值。 该变量没有包含在具有其他变量的不变式中。 FROM:http://baike.baidu.com/link?url=JSaHmxjUOb45xvhQFmOQstmmutAjrWrIdLlL_DUEfMzg_4bUNxlBfUb2okHOOg5K0XpNqZd-w0_Jej42lDoIrK 本文转自wauoen51CTO博客,原文链接:http://blog.51cto.com/7183397/1604659,如需转载请自行联系原作者

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

Android ContentObserver

想象一个场景: 有个TextView, 用来显示数据库一个表的数据总数. 用户通过UI界面对数据进行CRUD的操作. 这个TextView如何实时监控并更新显示数据总数? 目录: 第一节ContentObserver的感性认识 第二节3个重点 第三节具体实现 这里比较便捷且高效的方案是使用ContentObserver. 前提是已经建立了ContentProvider的支持. 先分析了一些网上广为流传了一个监控SMS变化的Observer例子. 画个图便于ContentObserver的感性认识. 通过这个图,主要了解3点就可以: 1, 建立继承自ContentObserver的对象,实现其onChange()方法. 2, 在目标Activity中注册和解除. 3, 在UI线程中, 用Handler接收来自Observer发出的Message, 更新UI. 思路有了, 就看具体的实现了. 一. 首先是建立一个继承自ContentObserver的对象. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class TAGContentObserver extends ContentObserver{ private Context mContext; private Handler mHandler; public static final int TAG_DB_CHANGE = 921 ; public TAGContentObserver(Context context, Handler handler) { super (handler); mContext = context; mHandler = handler; } @Override public void onChange( boolean selfChange) { //数据变化, 重新查询最新结果. Cursor cursor = mContext.getContentResolver().query(TAGDBOpenHelper.CONTENT_URI, null , null , null , null ); //发送Message. 此Handler定义在Activity中, 拆开Message得到结果更新TextView. mHandler.obtainMessage(TAG_DB_CHANGE, cursor.getCount(), 0 ).sendToTarget(); } } 重点是实现其onChange()方法, 如注释所写. onChange可以理解为在得到数据变化的通知之后, Observer做的事情. 此例子中是重新查询表的数据总数. 二. 在Activity中注册和解除. 1 2 3 //注册观察者 ContentObserver observer = new TAGContentObserver(MainActivity. this , mMyHandler); getContentResolver().registerContentObserver(TAGDBOpenHelper.CONTENT_URI, true , observer); 1 2 //解除观察者 getContentResolver().unregisterContentObserver(observer); 注册和解除可以根据需要, 比如分别放在Activity的onCreate()和onDestroy()方法中. 关于这个CONTENT_URI, 是自定义的, 如: 1 2 3 public static final String TABLE_NAME_TAG = "tag" ; public static final String AUTHORITY = "com.lichen.tagprovider" ; public static final Uri CONTENT_URI = Uri.parse( "content://" +TAGDBOpenHelper.AUTHORITY+ "/" +TABLE_NAME_TAG); 此Observer的目的可以说是监听或者观察这个URI的变化. 三. 在UI线程中, 用Handler接收来自Observer发出的Message, 更新UI. 1 2 3 4 5 6 7 8 9 @Override public void handleMessage(Message msg) { switch (msg.what) { case TAGContentObserver.TAG_DB_CHANGE: TextView tagNum = (TextView) findViewById(R.id.tag_total_num); tagNum.setText( "TAG总数: " + msg.arg1); break ; } } 到这里, 注册观察者Observer, 数据变化后重新查询数据库, 得到结果异步用Handler来更新UI. 看起来好像齐全了, 其实还有谁在什么时候通知观察者数据变化了的问题. 四. 在ContentProvider中添加通知数据变化. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 @Override public Uri insert(Uri uri, ContentValues values) { db = dbHelper.getWritableDatabase(); long rowId = db.insert(TAGDBOpenHelper.TABLE_NAME_TAG, "" , values); if (rowId > 0 ) { Uri newUrl = ContentUris.withAppendedId(TAGDBOpenHelper.CONTENT_URI, rowId); //通知数据变化 getContext().getContentResolver().notifyChange(newUrl, null ); return newUrl; } return null ; } @Override public int delete(Uri uri, String where, String[] whereArgs) { db = dbHelper.getWritableDatabase(); int count = 0 ; switch (matcher.match(uri)) { case TAGDBOpenHelper.TAG: count = db.delete(TAGDBOpenHelper.TABLE_NAME_TAG, where, whereArgs); break ; case TAGDBOpenHelper.TAG_ID: long parseId = ContentUris.parseId(uri); where = " _id = " + parseId ; count = db.delete(TAGDBOpenHelper.TABLE_NAME_TAG, where, null ); break ; } //通知数据变化 getContext().getContentResolver().notifyChange(uri, null ); return count; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { db = dbHelper.getReadableDatabase(); int match = matcher.match(uri); Cursor cursor = null ; switch (match) { case TAGDBOpenHelper.TAG: cursor = db.query(TAGDBOpenHelper.TABLE_NAME_TAG, null , null , null , null , null , null ); cursor.setNotificationUri(getContext().getContentResolver(), uri); //通知数据变化 break ; } return cursor; } 这样, 这个TextView就可以实时监控并更新显示数据总数了. 本文转自chainli 51CTO博客,原文链接:http://blog.51cto.com/lichen/1205628,如需转载请自行联系原作者

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

Android SharedPreferences

一,SharedPreferences简介 SharedPreferences是轻量级存储类,只能存放基本数据类型,且只能在本程序中使用,一般用于存放软件的配置参数(字体,颜色,位置,默认参数等),整体效率俩看不是特别的高,但是对于常规的轻量级而言,比SQLite要好不少。 SharedPreferences是以键值对来存储应用程序的配置信息的一种方式,基本上和J2SE(java.util.prefs.Preferences)中的用法一样。存放的数据在底层是以xml文件的格式存储在设备中的,存放于/data/data/PACKAGE_NAME/shared_prefs目录下面。 二, SharedPreferences基本使用方法 可通过context.getSharedPreferences (Stringname, int mode)或者Activity. getSharedPreferences (int mode)方法获得SharedPreferences对象 name:存储的xml文件名字,若不存在则会创建该xml文件. mode:操作模式有MODE_PRIVATE(0),MODE_WORLD_READABLE(1),MODE_WORLD_WRITEABLE(2)三种一般用第一个就可以了. 然后调用SharedPreferences对象的edit()方法,使其处于可编辑状态,才可写入数据,代码如下: Editor editor = sharedPreferences.edit(); editor.putInt("grade", 2008); editor.putString("team_name", "luckyXmobile"); editor.commit();//提交偏好变化到所编辑的xml <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="team_name">luckyXmobile</string> <int name="grade" value="2008" /> </map> 读取数据则只需要获得SharedPreferences对象即可: sharedPreferences.getString("team_name", "luckyXmobile"); sharedPreferences.get Int("grade", 2008); 若Preferences中不存在这个值,那么后面的参数就作为默认值返回,这样会省去为空的判断。 本文转自HDDevTeam 51CTO博客,原文链接:http://blog.51cto.com/hddev/622436,如需转载请自行联系原作者

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

Android:JSON

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 // 输出结果为: // { // "function":"功能" // "text":11111, // "key":{"age":23,"name":"tom"}, // "user":[ // {"age":23,"name":"jem"}, // {"age":32,"jerry":"nay"} // ], // } private void btn2Click() //输出至服务端 { JSONObject jsonobj2 = new JSONObject(); JSONObject jsonobj1 = new JSONObject(); JSONArray jsonarr = new JSONArray(); try { jsonobj1.put( "function" , "功能" ); jsonobj1.put( "text" , 11111 ); jsonobj2.put( "name" , "tom" ); jsonobj2.put( "age" , 23 ); jsonobj1.put( "key" , jsonobj2); jsonarr.put( new JSONObject().put( "name" , "jem" ).put( "age" , 23 )); jsonarr.put( new JSONObject().put( "jerry" , "nay" ).put( "age" , 32 )); jsonobj1.put( "user" , jsonarr); String str = jsonobj1.toString(); textView.setText(str); Log.e( "d" , str); } catch (JSONException e) { e.printStackTrace(); } } private void btn1Click() //从服务端获取数据 { try { JSONObject jsonObject = new JSONObject(json); JSONObject jsonObject1 = jsonObject.getJSONObject( "category" ); String str = jsonObject1.getString( "@scheme" ); textView.setText(str); } catch (JSONException e) { e.printStackTrace(); } } String json = "{'category':{'@scheme':'http://www.douban.com/2007#kind','@term':'http://www.douban.com/2007#book'},'db:tag':[{'@count':111,'@name':'片山恭一'},{'@count':51,'@name':'日本'},{'@count':43,'@name':'日本文学'},{'@count':31,'@name':'满月之夜白鲸现'},{'@count':28,'@name':'小说'},{'@count':10,'@name':'爱情'},{'@count':7,'@name':'純愛'},{'@count':6,'@name':'外国文学'}],'title':{'$t':'满月之夜白鲸现'},'author':[{'name':{'$t':'[日] 片山恭一'}}],'summary':{'$t':'那一年,是听莫扎特、钓鲈鱼和家庭破裂的一年。说到家庭破裂,母亲怪自己当初没有找到好男人,父亲则认为当时是被狐狸精迷住了眼,失常的是母亲,但出问题的是父亲……。'},'link':[{'@rel':'self','@href':'http://api.douban.com/book/subject/1220562'},{'@rel':'alternate','@href':'http://book.douban.com/subject/1220562/'},{'@rel':'image','@href':'http://img3.douban.com/spic/s1747553.jpg'},{'@rel':'mobile','@href':'http://m.douban.com/book/subject/1220562/'}],'db:attribute':[{'$t':'7543632608','@name':'isbn10'},{'$t':'9787543632608','@name':'isbn13'},{'$t':'满月之夜白鲸现','@name':'title'},{'$t':'180','@name':'pages'},{'$t':'豫人','@name':'translator'},{'$t':'[日] 片山恭一','@name':'author'},{'$t':'15.00元','@name':'price'},{'$t':'青岛出版社','@name':'publisher'},{'$t':'平装','@name':'binding'},{'$t':'2005-1','@name':'pubdate'}],'id':{'$t':'http://api.douban.com/book/subject/1220562'},'gd:rating':{'@min':0,'@numRaters':289,'@average':'7.0','@max':10}}" ; 本文转自 glblong 51CTO博客,原文链接:http://blog.51cto.com/glblong/1212834,如需转载请自行联系原作者

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

Android:ListFragment

MyListFragment类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class MyListFragment extends ListFragment //自身带了一个listview,直接onCreate即可 { private String[] mStr = new String[]{ "sdf" , "dsaf" , "dsafd" , "fsdgd" }; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); //直接setListAdapter setListAdapter( new ArrayAdapter<String>(getActivity(), R.layout.simple_list_item_1,mStr)); } //监听listview @Override public void onListItemClick(ListView l, View v, int position, long id) { super .onListItemClick(l, v, position, id); } } 本文转自 glblong 51CTO博客,原文链接:http://blog.51cto.com/glblong/1229560,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

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等操作系统。

用户登录
用户注册