1、内容提供者是让当前的app的数据可以让其他应用访问,其他应该可以通过内容提供者访问当前app的数据库

contentProvider的主要目的是提供一个开发的接口,让其他的应该能够访问当前应用的数据

2、建立的操作类必须继承自定义的内容提供者必须继承ContentProvider

3、创建的创建的PersonProvider必须在应用的主包名和主包名的子目录下,现在应用的主包名是 package="test.weiyuan.sqllite1"

4、内容提供者编写好之后需要在清单文件中进行注册,Android的四大组件都需要在清单文件中进行注册,因为provide是让外部的应用通过provide能够访问当前应用的数据,所以需要指明provide的访问路径   android:authorities,一般采用包名+provider的名字的形式

我们看下清单配置文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="test.weiyuan.sqllite1" ><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" >//对内容提供者进行注册<providerandroid:authorities="test.weiyuan.sqllite1.PersonProvider"android:name=".PersonProvider"android:exported="true"></provider><activityandroid:name=".MyActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

上面的三个属性必须必须填写,其中Android:exported为true表示该数据允许外面的程序访问,不要忘记填写

整个程序的代码框架也是采用mvc的架构

我们来一一分析

DbOpenHelper 类:
package dB;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;public class DbOpenHelper extends SQLiteOpenHelper
{public DbOpenHelper(Context context) {super(context, "wy.db", null, 2);}@Overridepublic void onCreate(SQLiteDatabase db){db.execSQL("CREATE TABLE person(personid integer primary key autoincrement, name varchar(20), phone VARCHAR(12) NULL)");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}

业务库操作接口类:

可以有下面的两种方式操作数据库:

/*** 文件名:PersonService.java* 版权:版权所有 (C) 中国电科30所三部* 描述:* 修改人: wei.yuan* 修改时间:2015/1/9* 修改内容:新增*/
package service;import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;import java.util.ArrayList;
import java.util.List;import dB.DbOpenHelper;
import domain.Person;/*** 项目名称:SQLLite1* 类描述:* 创建人:wei.yuan* 创建时间:2015/1/9 11:08* 修改人:wei.yuan* 修改时间:2015/1/9 11:08* 修改备注:* 版权:版权所有 (C) 中国电科30所三部*/
public class PersonService {
private DbOpenHelper dbOpenHelper;public PersonService(Context context) {this.dbOpenHelper = new DbOpenHelper(context);}public void save(Person person){SQLiteDatabase db = dbOpenHelper.getWritableDatabase();db.execSQL("insert into person(name, phone) values(?,?)",new Object[]{person.getName(), person.getPhone()});}/*** 删除记录* @param name 记录ID*/public void delete(String name,String phone){SQLiteDatabase db = dbOpenHelper.getWritableDatabase();db.execSQL("delete from person where name=? and phone=?", new Object[]{name,phone});}/*** 更新记录* @param person*/public void update(Person person,String name,String phone){SQLiteDatabase db = dbOpenHelper.getWritableDatabase();db.execSQL("update person set name=?,phone=? where name=? and phone=?",new Object[]{person.getName(), person.getPhone(),name,phone});}/*** 查询记录* @param name 记录ID* @return*/public Person find(String name,String phone){SQLiteDatabase db = dbOpenHelper.getReadableDatabase();Cursor cursor = db.rawQuery("select * from person where name=? and phone = ?", new String[]{name,phone});if(cursor.moveToNext()){int personid = cursor.getInt(cursor.getColumnIndex("personid"));String name1 = cursor.getString(cursor.getColumnIndex("name"));String phone1 = cursor.getString(cursor.getColumnIndex("phone"));return new Person( name1, phone1);}cursor.close();return null;}/*** 分页获取记录* @param offset 跳过前面多少条记录* @param maxResult 每页获取多少条记录* @return*/public List<Person> getScrollData(int offset, int maxResult){List<Person> persons = new ArrayList<Person>();SQLiteDatabase db = dbOpenHelper.getReadableDatabase();Cursor cursor = db.rawQuery("select * from person order by personid asc limit ?,?",new String[]{String.valueOf(offset), String.valueOf(maxResult)});while(cursor.moveToNext()){int personid = cursor.getInt(cursor.getColumnIndex("personid"));/*这里也可以写成*   String name = cursor.getString(1);String phone = cursor.getString(2);默认的表自带的id字段为0 ,name为第一个字段所有为1 ,phone为第二个字段为2*/String name = cursor.getString(cursor.getColumnIndex("name"));String phone = cursor.getString(cursor.getColumnIndex("phone"));persons.add(new Person( name, phone));}cursor.close();return persons;}/*** 获取记录总数* @return*/public long getCount(){SQLiteDatabase db = dbOpenHelper.getReadableDatabase();Cursor cursor = db.rawQuery("select count(*) from person", null);cursor.moveToFirst();long result = cursor.getLong(0);//统计之后只有一个默认的字段,所以为0
        cursor.close();return result;}/*使用 SimpleCursorAdapter加装数据的时候,创建的数据库表的主键必须是_id,* 这里我们使用personid as _id,将创建表的主键personid变成_id* 返回cursor对象的时候,千万不能关闭cursor对象:cursor.close();*/public Cursor getScrollCursorData(int offset, int maxResult){List<Person> persons = new ArrayList<Person>();SQLiteDatabase db = dbOpenHelper.getReadableDatabase();Cursor cursor = db.rawQuery("select personid as _id,name,phone from person order by personid asc limit ?,?",new String[]{String.valueOf(offset), String.valueOf(maxResult)});return cursor;//返回cursor对象之前,千万不能关闭cursor对象cursor.close();
    }}

方式二:

package service;import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;import java.util.ArrayList;
import java.util.List;import dB.DbOpenHelper;
import domain.Person;public class OtherPersonService {
private DbOpenHelper dbOpenHelper;public OtherPersonService(Context context) {this.dbOpenHelper = new DbOpenHelper(context);}public void save(Person person){SQLiteDatabase db = dbOpenHelper.getWritableDatabase();ContentValues values = new ContentValues();values.put("name",person.getName());values.put("phone",person.getPhone());db.insert("person",null,values);}/*** 删除记录* @param name 记录ID*/public void delete(String name,String phone){SQLiteDatabase db = dbOpenHelper.getWritableDatabase();/* db.execSQL("delete from person where name=? and phone=?", new Object[]{name,phone});*/db.delete("person", "name=? and phone= ?", new String[]{name ,phone});}/*** 更新记录* @param person*/public void update(Person person,String name,String phone){SQLiteDatabase db = dbOpenHelper.getWritableDatabase();/* db.execSQL("update person set name=?,phone=? where name=? and phone=?",new Object[]{person.getName(), person.getPhone(),name,phone});*/ContentValues values = new ContentValues();values.put("name",person.getName());values.put("phone",person.getPhone());db.update("person",values,"name=? and phone=?",new String[]{name ,phone});}/*** 查询记录* @param name 记录ID* @return*/public Person find(String name,String phone){SQLiteDatabase db = dbOpenHelper.getReadableDatabase();/* Cursor cursor = db.rawQuery("select * from person where name=? and phone = ?", new String[]{name, phone});*/Cursor  cursor = db.query("person",null,"name=? and phone=?",new String[]{name,phone},null,null,null);if(cursor.moveToNext()){int personid = cursor.getInt(cursor.getColumnIndex("personid"));String name1 = cursor.getString(cursor.getColumnIndex("name"));String phone1 = cursor.getString(cursor.getColumnIndex("phone"));return new Person( name1, phone1);}cursor.close();return null;}/*** 分页获取记录* @param offset 跳过前面多少条记录* @param maxResult 每页获取多少条记录* @return*/public List<Person> getScrollData(int offset, int maxResult){List<Person> persons = new ArrayList<Person>();SQLiteDatabase db = dbOpenHelper.getReadableDatabase();/* Cursor cursor = db.rawQuery("select * from person order by personid asc limit ?,?",*/Cursor  cursor = db.query("person",null,null,null,null,null,"personid asc",offset+ ","+ maxResult);while(cursor.moveToNext()){int personid = cursor.getInt(cursor.getColumnIndex("personid"));/*这里也可以写成*   String name = cursor.getString(1);String phone = cursor.getString(2);默认的表自带的id字段为0 ,name为第一个字段所有为1 ,phone为第二个字段为2*/String name = cursor.getString(cursor.getColumnIndex("name"));String phone = cursor.getString(cursor.getColumnIndex("phone"));persons.add(new Person( name, phone));}cursor.close();return persons;}/*** 获取记录总数* @return*/public long getCount(){SQLiteDatabase db = dbOpenHelper.getReadableDatabase();/*Cursor cursor = db.rawQuery("select count(*) from person", null);*/Cursor cursor = db.query("person", new String[]{"count(*)"}, null, null, null, null, null);cursor.moveToFirst();long result = cursor.getLong(0);//统计之后只有一个默认的字段,所以为0
        cursor.close();return result;}/*使用 SimpleCursorAdapter加装数据的时候,创建的数据库表的主键必须是_id,* 这里我们使用personid as _id,将创建表的主键personid变成_id* 返回cursor对象的时候,千万不能关闭cursor对象:cursor.close();*/public Cursor getScrollCursorData(int offset, int maxResult){List<Person> persons = new ArrayList<Person>();SQLiteDatabase db = dbOpenHelper.getReadableDatabase();Cursor cursor = db.rawQuery("select personid as _id,name,phone from person order by personid asc limit ?,?",new String[]{String.valueOf(offset), String.valueOf(maxResult)});return cursor;//返回cursor对象之前,千万不能关闭cursor对象cursor.close();
    }
}

javaBenn对象:

package domain;public class Person
{private String name;private String phone;@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", phone='" + phone + '\'' +'}';}public Person(String name, String phone) {this.name = name;this.phone = phone;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}
}

下面也是我们最为关键的内容提供者操作类:通过该类其他的应该就可以访问当前应用的数据,只要是业务操作,业务操作的异常都不要内部进行try catch捕获,而应该将业务操作的异常返回给调用者,当调用者进行业务操作的时候,如果遇到了异常就知道该业务操作是成功还是失败了,然后做出相应的处理。相当的关键

package test.weiyuan.sqllite1;import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;import dB.DbOpenHelper;/*** Created by wei.yuan on 2015/6/3.* 一定要在清单文件中对内容提供者进行注册* PersonProvider必须在应用的包名目录下或者包名的子目录下*/
public class PersonProvider extends ContentProvider {private DbOpenHelper dbOpenHelper;//该类用于检测的外部应用输入的URL是否正确,如果正确返回码就是codePerson,不正确返回UriMatcher.NO_MATCHprivate    static  final int codePerson = 1;private    static  final int codePerson1 = 2;//该类用于检测的外部应用输入的URL是否正确,如果不正确返回码就是new UriMatcher(UriMatcher.NO_MATCH)构造函数中的参数,这里是UriMatcher.NO_MATCHprivate    static  final UriMatcher  uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);static{//这个url表示对整个person表进行操作,如果url匹配返回的值是codePerson uriMatcher.addURI("test.weiyuan.sqllite1.PersonProvider","person",codePerson);//这个url表示对person表中的某个记录进行操作,#表示的是数字,就是对应的person表中的某个记录// android中#代表数字,*表示任意的字符,如果url匹配返回的值是codePerson1 uriMatcher.addURI("test.weiyuan.sqllite1.PersonProvider","person/#",codePerson1);}//onCreate()之后被调用一次,在调用的时候创建数据库,记得返回值为true
    @Overridepublic boolean onCreate() {dbOpenHelper = new DbOpenHelper(getContext());return true;}//查询数据表的数据
    @Overridepublic Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {SQLiteDatabase database = dbOpenHelper.getWritableDatabase();switch (uriMatcher.match(uri)){//更新整个表case codePerson:return database.query("person",projection,selection,selectionArgs,null,null,sortOrder);//更新表中的某条记录case  codePerson1:long  row_id = ContentUris.parseId(uri);String where = " personid="+row_id;Log.i("weiyuan",""+row_id);if (selection!=null&&!"".equals(selection.trim())){where  += "and "+selection;}return database.query("person",null,where,selectionArgs,null,null,sortOrder);default://如果传人的url不正确,抛出一个异常提示用户throw  new IllegalArgumentException("this is a unkown url-->"+uri);}}//返回要操作数据的内容类型,如txt文本就是plain/text类型
    @Overridepublic String getType(Uri uri) {switch (uriMatcher.match(uri)){//操作的是多条数据记录case codePerson:return  "vnd.android.cursor.dir/person";//操作的是单条数据case  codePerson1:return  "vnd.android.cursor.item/person";default:throw  new IllegalArgumentException("this is a unkown url-->"+uri);}}//可以让外面的应用向内容提供者插入数据
    @Overridepublic Uri insert(Uri uri, ContentValues values) {SQLiteDatabase database = dbOpenHelper.getWritableDatabase();switch (uriMatcher.match(uri)){case codePerson://这里如果values为空,就必须需要第二个参数有值这里为"name",如果values有值,第二个参数默认为空值long rowid = database.insert("person",null,values);// Uri insertUri = Uri.parse("context://test.weiyuan.providers.PersonProvider/person/"+rowid);可以使用下面的方法http://blog.csdn.net/feng88724/article/details/6331396Uri insertUri = ContentUris.withAppendedId(uri,rowid);if(database!=null){database.close();}return  insertUri;default://如果传人的url不正确,抛出一个异常提示用户if(database!=null){database.close();}throw  new IllegalArgumentException("this is a unkown url-->"+uri);}}//返回值int表示你删除了多少条记录
    @Overridepublic int delete(Uri uri, String selection, String[] selectionArgs){SQLiteDatabase database = dbOpenHelper.getWritableDatabase();int num = 0;//删除的记录数目switch (uriMatcher.match(uri)){//删除整个表case codePerson:num =database.delete("preson",selection,selectionArgs);if(database!=null){database.close();}break;//删除表中的某条记录case  codePerson1://  从url中要删除的记录的idlong  row_id = ContentUris.parseId(uri);String where = " personid="+ row_id;//外面传递进行的条件if (selection!=null&&!"".equals(selection.trim())){where  += "and "+selection;}num = database.delete("person",where,selectionArgs);if(database!=null){database.close();}break;default://如果传人的url不正确,抛出一个异常提示用户throw  new IllegalArgumentException("this is a unkown url-->"+uri);}return num;}@Overridepublic int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {SQLiteDatabase database = dbOpenHelper.getWritableDatabase();switch (uriMatcher.match(uri)){//更新整个表case codePerson:database.update("preson",values,selection,selectionArgs);if(database!=null){database.close();}break;//更新表中的某条记录case  codePerson1:long  row_id = ContentUris.parseId(uri);String where = " personid="+row_id;Log.i("weiyuan",""+row_id);if (selection!=null&&!"".equals(selection.trim())){where  += "and "+selection;}database.update("person",values,where,selectionArgs);if(database!=null){database.close();}break;default:if(database!=null){database.close();}//如果传人的url不正确,抛出一个异常提示用户throw  new IllegalArgumentException("this is a unkown url-->"+uri);}return 0;}
}

注意点2:

首先先让数据库这个app运行起来,现在我们在新建立一个app,在这个app中访问数据库app中的数据

我们使用测试工具类的办法来实现Android studio 中测试类必须继承AndroidTestCase,该类中的所有测试方法必须以test开头

package testSQLLite;import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;/*** Created by wei.yuan on 2015/6/3.*/
public class TestContextProvider extends AndroidTestCase {final  static String  TAG ="weiyuan";//测试插入数据public  void testInsert() throws Exception{//注意uri中的字符串一般是小写,下面写成大写不太规范,一般遵循包名+类名,注意conten不要写成context了Uri uri = Uri.parse("content://test.weiyuan.sqllite1.PersonProvider/person");ContentResolver resolver = getContext().getContentResolver();ContentValues values = new ContentValues();values.put("name","aonier");values.put("phone","28");// 下面 resolver.insert(uri,values)这个函数本质上是调用了PersonProvider这个内容提供者中的insert函数
         resolver.insert(uri,values);Log.i(TAG,"数据插入成功!");}//删除数据public  void testDelete() throws Exception{Uri uri = Uri.parse("content://test.weiyuan.sqllite1.PersonProvider/person/1");long id = ContentUris.parseId(uri);Log.i(TAG,id+"");ContentResolver resolver = getContext().getContentResolver();resolver.delete(uri,null,null);Log.i(TAG,"数据删除成功!");}//更新表中的数据public  void testUpdate() throws Exception{Uri uri = Uri.parse("content://test.weiyuan.sqllite1.PersonProvider/person/1");long id = ContentUris.parseId(uri);ContentResolver resolver = getContext().getContentResolver();ContentValues values = new ContentValues();values.put("name","aonier");values.put("phone","34");resolver.update(uri,values,null,null);Log.i(TAG, "数据更新成功!");}//查询数据表的数据public  void testQuery() throws Exception{Uri uri = Uri.parse("content://test.weiyuan.sqllite1.PersonProvider/person");ContentResolver resolver = getContext().getContentResolver();Cursor cursor =resolver.query(uri, null, null, null, null);while (cursor.moveToNext()){Log.i(TAG,"数据查询成功!"+cursor.getString(cursor.getColumnIndex("name")));}//加载自定义适配器的数据
}}

对应上面两种数据库的两种业务操作也可以使用测试类的方式进行测试:

package testSQLLite;import android.test.AndroidTestCase;
import android.util.Log;import java.util.List;import dB.DbOpenHelper;
import domain.Person;
import service.OtherPersonService;public class OtherTestSQLLite extends AndroidTestCase {final  static String  TAG ="weiyuan";public  void testCreateDb(){DbOpenHelper dbOpenHelper = new DbOpenHelper(getContext());dbOpenHelper.getWritableDatabase();Log.i(TAG,"数据库创建成功");}public void testSave() throws Exception{OtherPersonService service = new OtherPersonService(this.getContext());for(int i = 0;i<20;i++){service.save(new Person("weiyuan"+i,"12345"+i));}Log.i(TAG,"数据保存成功");}/*主要查找的是姓名和电话一起查找,只要满足了姓名和电话,才正确*/public void testFind() throws Exception{OtherPersonService service = new OtherPersonService(this.getContext());Person person = service.find("weiyuan1","123451");Log.i(TAG, person.toString());Log.i(TAG,"数据查找成功");}/*删除某个记录*/public void testdelete() throws Exception{OtherPersonService service = new OtherPersonService(this.getContext());service.delete("weiyuan1","123451");Log.i(TAG,"数据删除成功");}/*给新某个记录*/public void testupdate() throws Exception{OtherPersonService service = new OtherPersonService(this.getContext());service.update(new Person("chendong","456789"),"weiyuan2","123452");Log.i(TAG, "数据修改成功");}/*获得分页的数据*/public void testScrollData() throws Exception{OtherPersonService service = new OtherPersonService(this.getContext());List<Person> persons = service.getScrollData(0, 5);for(Person person : persons){Log.i(TAG, person.toString());}}public void testCount() throws Exception{OtherPersonService service = new OtherPersonService(this.getContext());long result = service.getCount();Log.i(TAG, result+"");}}

package testSQLLite;import android.test.AndroidTestCase;
import android.util.Log;
import android.widget.Toast;import java.util.List;import dB.DbOpenHelper;
import domain.Person;
import service.PersonService;public class TestSQLLite extends AndroidTestCase {final  static String  TAG ="weiyuan";public  void testCreateDb(){DbOpenHelper dbOpenHelper = new DbOpenHelper(getContext());dbOpenHelper.getWritableDatabase();Log.i(TAG,"数据库创建成功");}public void testSave() throws Exception{PersonService service = new PersonService(this.getContext());for(int i = 0;i<20;i++){service.save(new Person("weiyuan"+i,"12345"+i));}Log.i(TAG,"数据保存成功");}/*主要查找的是姓名和电话一起查找,只要满足了姓名和电话,才正确*/public void testFind() throws Exception{PersonService service = new PersonService(this.getContext());Person person = service.find("chendong","456789");Log.i(TAG, person.toString());Log.i(TAG,"数据查找成功");}/*删除某个记录*/public void testdelete() throws Exception{PersonService service = new PersonService(this.getContext());service.delete("weiyuan1","123451");Log.i(TAG,"数据删除成功");}/*给新某个记录*/public void testupdate() throws Exception{PersonService service = new PersonService(this.getContext());service.update(new Person("chendong","456789"),"weiyuan2","123452");Log.i(TAG, "数据修改成功");}/*获得分页的数据*/public void testScrollData() throws Exception{PersonService service = new PersonService(this.getContext());List<Person> persons = service.getScrollData(0, 5);for(Person person : persons){Log.i(TAG, person.toString());}}public void testCount() throws Exception{PersonService service = new PersonService(this.getContext());long result = service.getCount();Log.i(TAG, result+"");}}

转载于:https://www.cnblogs.com/kebibuluan/p/6758252.html

黎活明8天快速掌握android视频教程--20_采用ContentProvider对外共享数据相关推荐

  1. Android学习笔记---20_采用ContentProvider对外共享数据, UriMatcher类使用介绍 ,ContentUris类使用介绍,使用ContentResolver操作Conte

    20_采用ContentProvider对外共享数据 ------------------------------------------ 1.比如通讯录,就是通过ContentProvider,实现 ...

  2. 让人才不再稀缺,让就业水到渠成 ——记传智播客总裁黎活明

    专访简介: 2017年3月21日,"传智专修学院成立大会暨揭牌仪式"在江苏沭阳文化艺术中心隆重举行.江苏宿迁市相关领导.沭阳县相关领导.互联网行业精英.相关媒体.传智播客及传智专修 ...

  3. 3G手机Android应用开发视频教程_黎活明老师的视频(第三天课程)总共有八天课程...

    下载地址:http://jiyanet.com/read.php?tid=402 转载于:https://www.cnblogs.com/javaspring/archive/2012/08/21/2 ...

  4. 3G手机Android应用开发视频教程_黎活明老师的视频(第五天课程)总共有八天课程...

    下载地址:http://jiyanet.com/read.php?tid=404 转载于:https://www.cnblogs.com/javaspring/archive/2012/08/22/2 ...

  5. 3G手机Android应用开发视频教程_黎活明老师的视频下载地址(总共有八天课程)

    视频下载地址:http://jiyanet.com/read.php?tid=404

  6. build.xml(黎活明安全管理部署文件)

    <?xml version="1.0"?> <!-- ====================================================== ...

  7. 快速掌握Android教程适合新手(4G)57讲

    搭建Android开发环境 创建与启动手机模拟器和学习使用ANDROID操作系统 开发与运行(卸载)第一个ANDROID应用 项目的目录结构与安装及启动过程分析 电话拔号器 查看应用输出的错误信息与如 ...

  8. Android基础知识巩固系列 Android之四大组件——ContentProvider(内容提供者)

    因为最近要面试,于是打算整理整理一下Android的基础知识,由于之前本人已经学习过大概的Android基础知识,这里主要讲这四大组件.五大存储.六大布局.网络请求等这些内容,其他一些等有时间再整理, ...

  9. 【Android架构GPS篇】之定位数据如何从GPS芯片到应用层

    原址:http://blog.csdn.net/u013686019/article/details/47444839 写在前面 在漫长的Android源码编译等待过程中,想起之前写过一部分的Andr ...

  10. 飞特商城后台管理系统是接私活利器,企业级快速开发框架 商城后台 取之开源,用之开源

    简介: 飞特后台管理系统是接私活利器,企业级快速开发框架 技术选型 注册中心:zookeeper 分布式治理框架 :dubbo 核心框架:Spring Boot 权限框架:Apache Shiro 模 ...

最新文章

  1. [LeetCode/LintCode] Factorial Trailing Zeros
  2. [ios]NSLock锁
  3. Puppet学习之文件管理
  4. [xsy2880]取石子游戏
  5. 2009.11网络工程师考试案例试题学习攻略(1)
  6. java计数循环及小技巧
  7. OpenCV在图像中添加文字,画点,画直线
  8. 通向成功的23个方法
  9. python和别的脚本语言_PHP与Python与其它脚本语言
  10. 我安装Microsoft SQLServer 2000时出现问题
  11. 实现百度右侧排名相关搜索全攻略
  12. Winform UI界面设计例程——ListView控件
  13. 网站分析基础概念之初访者
  14. 袋鼠云数据湖平台「DataLake」,存储全量数据,打造数字底座
  15. PMP-项目成本管理
  16. TCP协议-TCP连接管理
  17. python练习题:输入账号密码
  18. 易百纳rv1126 201版本开箱
  19. NoSQL Manager for MongoDB破解
  20. 攻城狮生活-2 让我支付空车费的司机

热门文章

  1. MPB:中科院植物所杨文强组-​莱茵衣藻遗传连锁分析方法
  2. 仿小米商城SpringBoot+Vue全栈项目开发实战文档
  3. Python数据分析案例篇(一)泰坦尼克号数据分析
  4. 有奖体验 CODING 产品,iPad Pro、HHKB 键盘等超级礼包等你来!
  5. Excel 录制宏 - 制作工资条
  6. 【ORA-RAC】ORA-15045: ASM file name '+DATA01' is not in reference form
  7. 暴笑新东方老师老罗语录(转)
  8. web服务器攻击与防御系统设计,网络安全-Web的入侵防御系统的设计与实现
  9. 使用ZYNQ实现单LUT内容的动态修改(一)PL端OOC设计流程
  10. 看小伙是怎么发现CSDN前10大佬之间的关系的