Skip to content

JavaBaas/JavaBaas_SDK_Android

Repository files navigation

#目录 ##一、SDK安装与初始化 ####SDK 手动安装:

下载SDK并解压得到如下文件:

├── JavaBaas-sdk-<版本号>.jar           // JavaBaas SDK核心模块
├── fastjson-<版本号>.jar               // JavaBaas SDK序列化模块
├── okhttp-<版本号>.jar                 // JavaBaas SDK网络请求模块
├── okio-<版本号>.jar                   // 七牛云存储SDK依赖模块
├── happy-dns-0.2.5.jar                // 七牛云存储SDK依赖模块
└── qiniu-android-sdk-<版本号>.jar      // 七牛云存储SDK核心模块

将解压出的模块导入到项目中。

####Maven自动导入安装(coming soon)

####SDK初始化:

新建一个类 App继承自Application 类:

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // 初始化参数依次为 this, AppKey, AppId, 后台服务器地址,
        // 获取InstallationId的回调(用来处理与InstallationId有关的操作,如绑定到用户等)
        JBCloud.init(this , "1f7049bfde7d440cb31210aa5e4d44ed" , "5645b2a574242e39eee89829" , "https://api.javabaas.com" , null);
    }
}

然后在AndroidManifest.xml中配置SDK所需的一些权限以及声明刚才创建的App

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

    <application
        android:name="com.javabaas.sample.App"
        ...
        >
        ...
    </application>

SDK配置完成,可以进行一些简单的访问测试:

public void onSave(View view) {
       final JBObject testC = new JBObject("testC");
       testC.put("testA", "测试A");
       testC.put("testB", "测试B");
       testC.saveInBackground(new SaveCallback() {
                @Override
                public void done(JBObject object) {
                    Log.d("ObjectTest" ,"保存成功 id=" + testC.getId());
                }

                @Override
                public void error(JBException e) {
                    Log.d("ObjectTest" ,"保存失败 "+e.getResponseErrorMsg);
                    e.printStackTrace();
                }
            });
}

##二、对象 ###2.1 JBObject JBOject是JavaBaas中的基础对象,也可以理解为JBOject对应着数据库表中的一条信息。

假如你在云端数据库中使用FoodLike表来记录用户最喜欢的食物,那么表中至少会有foodName(食品名称),userName(用户名称)属性,那么,你应该这样生成JBOject:

JBObject jbObject = new JBObject("FoodLike");
jbObject.put("foodName","dumpling");
jbObject.put("userName","ZhangSan");

有几点需要注意:

  • 每个JBOject都必须在云端有对应的数据库表和相应的字段。
  • 每个JBOject都有保留字段,分别为_id``acl``createdPlat``updatedPlat``createdAt``updatedAt,这些字段由系统自动生成和修改,不需要开发者进行指定。

###2.2 同步与异步 JavaBaas提供了数据检索,保存,更新,删除,查询的同步与异步的方法。

注: 在Android UI主线程中调用同步的方法,可能会导致UI主线程阻塞。所以,在UI主线程中请使用异步的方式。

###2.3 检索对象 如果你知道了云端中某条数据的objectId,那么可以通过以下代码获取此条数据对应的JBOject对象:

1.同步检索:
JBQuery<JBObject> jbQuery = JBQuery.getInstance("FoodLike");
jbQuery.whereEqualTo("_id", objectID);
JBObject result;
try {
		List<JBObject> resultList = jbQuery.find();
		result = resultList.get(0);
} catch (JBException e) {
		e.printStackTrace();
}

2.异步检索:
JBQuery<JBObject> jbQuery = JBQuery.getInstance("FoodLike");
jbQuery.whereEqualTo("_id", objectID);
jbQuery.findInBackground(new FindCallback<JBObject>() {
		@Override
		public void done(List<JBObject> resultList) {
			JBObject result = resultList.get(0);                    
		}
		
		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

###2.4 保存对象 如2.1所示,假如你在本地生成一个JBObject之后,那么可以使用以下代码将其保存至云端:

1.同步保存:
try {
		jbObject.save();
		Log.d("ObjectTest" , "保存成功 "+ jbObject.getId());
} catch (JBException e) {
		e.printStackTrace();
}

2.异步保存:
jbObject.saveInBackground(new SaveCallback() {
         @Override
         public void done(JBObject object) {  
              Log.d("ObjectTest" , "保存成功 "+ object.getId());
         }

         @Override
         public void error(JBException e) {
         		e.printStackTrace();
         }
});

###2.5 更新对象 如果你知道了云端中某条数据的objectId,那么可以通过以下代码更新云端对应的数据:

1.同步更新:
JBObject jbObject = new JBObject("FoodLike");
jbObject.setId(objectId);
jbObject.put("foodName","hamburger");
try {
		jbObject.save();
		Log.d("ObjectTest", "修改成功了");
} catch (JBException e) {
		e.printStackTrace();
}

2.异步更新:
JBObject jbObject = new JBObject("FoodLike");
jbObject.setId(objectId);
jbObject.put("foodName","hamburger");
jbObject.saveInBackground(new SaveCallback() {
		@Override
		public void done(JBObject object) {
			Log.d("ObjectTest", "修改成功了");
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

###2.6 删除对象 如果你知道了云端中某条数据的objectId,那么可以通过以下代码删除云端对应的数据:

1.同步删除:
try {
		JBObject.deleteById("FoodLike", objectId);
		Log.d("ObjectTest", "删除成功了");
} catch (JBException e) {
		e.printStackTrace();
}

2.异步删除:
JBObject.deleteByIdInBackground("FoodLike", objectId, new DeleteCallback() {
		@Override
		public void done() {
			Log.d("ObjectTest", "删除成功了");
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

###2.7 关联对象

在数据存储中,类之间可能会有直接的关联关系。

比如,一个公民拥有一个唯一身份证。那么如果在一个公民对象中想指向一个身份证类的对象,那么可以通过以下代码来实现:

JBObject citizenObject = new JBObject("Citizen");

//实例化一个'身份证'对象,并将已知的Id赋值进去。
JBObject identificationCardObject = JBObject.createWithoutDate("IdentificationCard","babc5b153dc0401fb5fcd8ffaae0ddf6");

//将'身份证'对象赋值到'公民'对象中。
citizenObject.put("identificationCard", identificationCardObject);

//保存
citizenObject.saveInBackground(new SaveCallback() {
		@Override
		public void done(JBObject object) {
			Log.d("ObjectTest", "保存成功 " + object.getId());
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

###2.8 原子操作 很多应用都会用到计数器的功能,比如在一个新闻类的应用中,我们需要记录每条新闻的查看次数,可以使用以下代码:

//第一个参数为新闻对象所在的表名,第二个参数为新闻对象的id
JBObject testObject = JBObject.createWithoutData("News",objectId);
//第一个参数为要增加的字段名称,第二个参数为要增加的个数
testObject.incrementKeyInBackground("openCount", 1, new RequestCallback() {
		@Override
		public void done() {
			Log.d("ObjectTest", "自增成功");
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

针对上面的情况,还可以直接调用incrementKeyInBackground方法,来实现参数加1。

testObject.incrementKeyInBackground("openCount", new RequestCallback() {
		@Override
		public void done() {
			Log.d("ObjectTest", "自增成功");
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

###2.9 批量操作 (敬请期待)

###2.10 数据类型

目前我们支持的数据类型有:

String``Int``Float``Boolean以及Date``File``Object``Array类型

简单使用用例如下:

JBObject testObject = new JBObject("Test");

//String
testObject.put("testString", "测试");
//Int
testObject.put("testInt",1);
//Float
testObject.put("testFloat",1.111f);
//boolean
testObject.put("testBoolean", true);
//Date
testObject.put("testDate", new Date());
//Array
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
testObject.put("testArray", list);

testObject.saveInBackground(new SaveCallback() {
		@Override
		public void done(JBObject object) {
			Log.d("ObjectTest", "保存成功 " + object.getId());
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

##三、查询 SDK中提供了JBQuery类来满足应用不同条件下的查询需求。 ###3.1 基本查询 如果想查询指定表中的所有数据,可以使用以下代码:

1.同步查询:
JBQuery jbQuery = JBQuery.getInstance("Test");
List<JBObject> list;
try {
		list = jbQuery.find();
		Log.d("ObjectTest", "查询到的所有条数为" + list.size());
} catch (JBException e) {
		e.printStackTrace();
}

2.异步查询:
JBQuery jbQuery = JBQuery.getInstance("Test");
jbQuery.findInBackground(new FindCallback<JBObject>() {
		@Override
		public void done(List<JBObject> result) {
			Log.d("ObjectTest", "查询到的所有条数为" + result.size());
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

###3.2 约束查询 SDK支持多种约束查询条件,举例如下:

//限制查询条数为10条
jbQuery.setLimit(10);

//查询会跳过前两条
jbQuery.skip(2);

//查询'age'字段为'18'的
jbQuery.whereEqualTo("age",18);

###3.3 数组值查询 如果想查询数据库中某个字段包含在指定数组中的所有数据,可以添加以下限制条件:

List<Integer> list = new ArrayList<>();
list.add(18);
list.add(19);
list.add(20);

//查询年龄包含在指定数组中的所有数据
jbQuery.whereContainedIn("age", list);

###3.4 模糊查询

JavaBaas支持多种模糊查询条件,举例如下:

//查询所有name中包含'浩'字的
jbQuery.whereMatches("name","浩");

//查询所有name中以'王'开头的
jbQuery.whereStartsWith("name","王");

//查询所有name中以'超'结尾的
jbQuery.whereEndsWith("name","超");

###3.5 关系查询

因为在数据存储中,类之间可能会有直接的关联关系。比如一个Student对象studentA,它的英语老师会指向一个Teacher的对象teacherA。

那么,如果我要查询所有英语老师为teacherA的Student对象,可以使用以下代码:

JBQuery<JBObject> jbQuery  = JBQuery.getInstance("Student");
//第二个参数为teacherA的id
JBObject teacherA = JBObject.createWithoutData("Teacher","939666c47ded4fafb1a8403b830cdc98");
jbQuery.whereEqualTo("englishTeacher",teacherA);
jbQuery.findInBackground(new FindCallback<JBObject>() {
		@Override
		public void done(List<JBObject> result) {
			Log.d("ObjectTest", "查询成功,查询到的所有条数为" + result.size());
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

当涉及到云端中的三张表的关系查询时,就需要用到whereMatchesKeyInQuery方法。

假如,在一个图书馆系统中,用户可以关注多个类别,如"经典著作"类别,"历史地理"类别。

如果要查询用户关注的类别中的所有书籍,可以使用以下代码:

JBQuery<JBObject> mainQuery = JBQuery.getInstance("Book");
JBQuery<JBObject> subQuery = JBQuery.getInstance("SubscriptionCategory");
subQuery.whereEqualTo("user", JBUser.getCurrentUser());
mainQuery.whereMatchesKeyInQuery("category", "subscriptionCategory", "Category", subQuery);
mainQuery.findInBackground(new FindCallback<JBObject>() {
		@Override
		public void done(List<JBObject> result) {
			Log.d("ObjectTest", "查询成功,查询到的所有条数为" + result.size());
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

当我们需要将JBQuery查询对象融合起来一起查询的时候,可以使用静态方法or来实现

例如查询Student中年龄大于18或者小于10的对象,可以使用以下代码:

JBQuery<JBObject> lotsOfQuery = JBQuery.getInstance("Student");
lotsOfQuery.whereGreaterThan("age", 18);

JBQuery<JBObject> fewQuery = JBQuery.getInstance("Student");
fewQuery.whereLessThan("age", 10);

List<JBQuery<JBObject>> list = new ArrayList<>();
list.add(lotsOfQuery);
list.add(fewQuery);

JBQuery<JBObject> mainQuery = JBQuery.or(MainActivity.this,list);
mainQuery.findInBackground(new FindCallback<JBObject>() {
		@Override
		public void done(List<JBObject> result) {
			Log.d("ObjectTest", "查询成功,查询到的所有条数为" + result.size());
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

###3.6 缓存查询 缓存查询是将查询的结果缓存到本地,当程序处于没有网络连接的状态时,就可以通过缓存查询查出上一次相同查询的结果。 JavaBaas支持的缓存类型有:

CACHE_ELSE_NETWORK:先从缓存中获取数据,如果本地没有缓存,从网络中获取数据。
CACHE_ONLY:只从缓存中获取数据,
CACHE_THEN_NETWORK:先从缓存中获取数据,再从网络中获取数据。
IGNORE_CACHE:不从缓存中获取数据,只从网络中获取数据,并且获取到的数据不存入缓存中。这是JavaBaas默认的查询方式。
NETWORK_ELSE_CACHE:先从网络中获取数据,再从缓存中获取数据
NETWORK_ONLY:只从网络中获取数据,从网络中获取的数据会存入缓存中。

使用方法如下:

JBQuery<JBObject> jbQuery = JBQuery.getInstance("Data");
jbQuery.setCachePolicy(JBQuery.CachePolicy.CACHE_ELSE_NETWORK);
jbQuery.findInBackground(new FindCallback<JBObject>() {
		@Override
		public void done(List<JBObject> result) {
			Log.d("ObjectTest", "查询成功,查询到的所有条数为" + result.size());
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

###3.7 计数查询

如果只是想知道数据库中指定条件的数据个数的话,可以使用计数查询,举例如下:

1.同步查询:
JBQuery jbQuery = JBQuery.getInstance("Test");
try {
		int count = jbQuery.count();
		Log.d("ObjectTest", "查询到的所有条数为" + count);
} catch (JBException e) {
		e.printStackTrace();
}

2.异步查询:
JBQuery jbQuery = JBQuery.getInstance("Test");
//查询'age'字段为'18'的
jbQuery.whereEqualTo("age",18);
jbQuery.countInBackground(new CountCallback() {
		@Override
		public void done(int count) {
			Log.d("ObjectTest", "查询到的所有条数为" + count);
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

##四、ACL权限控制

JavaBaas提供了ACL(访问控制列表)来管理数据的访问权限。

在默认情况下,数据是可读可写的,在特殊情况下,我们可以设置数据在特定的用户访问的权限。比如,Data表中存入某条数据,此条数据在用户A下才可写,而其它用户都只是可读权限。可以使用以下代码:

JBObject dataObject = new JBObject("Data");
dataObject.put("secretData", "100");
JBAcl acl = new JBAcl();
//此方法为设置数据全部可读
acl.setPublicReadAccess(true);
//第一个参数为用户A的userId,此方法为设置数据只有用户A可写。
acl.setWriteAccess(userAId, true);
dataObject.setACL(acl);

dataObject.saveInBackground(new SaveCallback() {
		@Override
		public void done(JBObject object) {
			Log.d("ObjectTest", "保存成功 ");
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

##五、文件JBFile ###5.1 JBFile JBFile允许你将文件存储到服务器中,常见的文件类型有:

  • 图片
  • 影像文件
  • 音乐文件
  • 其它二进制数据

###5.2 文件元数据 ###5.4 图像与缩略图获取(待定) ###5.5 进度提示 在JBFile的上传回调中可以获得上传的进度

例如,保存本地的一张图片到云端,并获取上传的进度,可以使用以下代码:

JBFile jbFile = new JBFile(new File(Environment.getExternalStorageDirectory() , "demo.jpg"));
jbFile.saveInBackground(new FileUploadCallback() {
		@Override
		public void done(JBFile jbFile) {
			Log.d("ObjectTest", "上传成功");
		}

		@Override
		public void error(JBException e) {
			Log.d("ObjectTest", "上传失败");
		}

		@Override
		public void onProgress(double percent) {
			Log.d("ObjectTest", "上传进度为" + percent);
		}
});

##六、用户JBUser

###6.1 JBUser JavaBaas提供了JBUser类来处理用户相关的功能。

需要注意的是,JBUser继承了JBObject,并在JBObject的基础上增加了一些对用户账户操作的功能。

###6.2 特殊属性 JBUser有几个特定的属性为:

  • username:用户的用户名(必须)
  • password:用户的密码(必须)
  • email:用户的电子邮箱(可选)
  • phone:用户的手机号码(可选)

设置属性的方法如下:

JBUser jbUser = new JBUser();
//设置用户名             
jbUser.setUsername("ZhangSan");        
//设置密码          
jbUser.setPassword("123456");
//设置手机号   
jbUser.setPhone("110");

###6.3 注册 用户注册的示例代码如下:

1.同步注册
JBUser jbUser = new JBUser();             
jbUser.setUsername("ZhangSan");               
jbUser.setPassword("123456");
jbUser.setPhone("110");
try {
		jbUser.signUp();
		Log.d("ObjectTest", "注册成功" + jbUser.getId());
} catch (JBException e) {
		e.printStackTrace();
}

2.异步注册
JBUser jbUser = new JBUser();
jbUser.setUsername("ZhangSan");
jbUser.setPassword("123456");
jbUser.setPhone("110");
jbUser.signUpInBackground(new SignUpCallback() {
		@Override
		public void done(JBUser jbUser) {
			Log.d("ObjectTest", "注册成功" + jbUser.getId());
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

###6.4 登录 当用户注册成功后,用户可以通过注册的用户名,密码登录到他们的账户。 用户登陆的示例代码如下:

//用户名、密码登录
String username = "ZhangSan";
String password = "123456";
JBUser.loginWithUsernameInBackground(username, password, new LoginCallback() {
		@Override
		public void done(JBUser jbUser) {
			Log.d("ObjectTest", "登陆成功" + jbUser.getId());
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

//第三方授权登录(目前仅支持需要传入从第三方平台获取到的accessToken和uid, 并传入登录平台(如QQ、微信微博等)的登陆的方法)
//第一个参数为accessToken,第二个参数为登陆的平台,第三个参数为uid
JBUser.JBThirdPartyUserAuth  jbThirdPartyUserAuth = new JBUser.JBThirdPartyUserAuth("OezXcEiiBSKSxW0eoylIeKszaZo3pw9ABL2UB", JBUser.JBThirdPartyUserAuth.SNS_QQ,"8343726DA09DB9830CC32486A4856E0A");
JBUser.loginWithSnsInBackground(jbThirdPartyUserAuth, new LoginCallback() {
		@Override
		public void done(JBUser jbUser) {
			Log.d("ObjectTest", "登陆成功" + jbUser.getId());
		}

		@Override
		public void error(JBException e) {
			e.printStackTrace();
		}
});

###6.5 当前用户 为了避免用户每次打开应用程序的时候都要登陆,可以使用本地缓存的currentUser对象

当用户注册或者登陆成功后,本地会生成一个currentUser对象,你可以使用此对象来进行判断用户是否登陆:

//使用currentUser对象进行判断
JBUser jbUser = JBUser.getCurrentUser();
if (jbUser!=null){
		Log.d("ObjectTest", "currentUser不为空,允许用户使用");
}else {
		Log.d("ObjectTest", "currentUser为空,此时可打开用户注册/登陆的界面");
}

清除缓存的currentUser对象。

JBUser.logout(new LogoutCallback() {
		@Override
		public void onLogout(boolean isSuccess) {
			if (isSuccess){
				Log.d("ObjectTest", "登出成功");
			}
		}
});

###6.6 修改密码 假如用户登录成功后,想改变自己的用户信息,可以通过以下代码来更新:

JBUser jbUser = JBUser.getCurrentUser();
if (jbUser!=null){
	jbUser.updatePassword("123456", "456789", new RequestCallback() {
			@Override
			public void done() {
				Log.d("ObjectTest", "修改成功");
			}

			@Override
			public void error(JBException e) {
				e.printStackTrace();
			}
	});
}

###6.7 SessionToken介绍 SessionTokenJBUser的一个非常特殊的属性,是 JBUser的内建字段。当用户注册成功后,自动生成且唯一。

当用户更改重置密码后,SessionToken也会被重置。

SessionToken的作用主要有两个方面:

  • 服务器用来校验用户登录与否
  • 保证在多设备登录同一账号情况下,用户账号安全

##七、设备与推送

_Installation是存在于云端的一个用来管理设备信息的默认表。

  • deviceToken : 设备的唯一标示符
  • deviceType : 对于Android设备来说,type就是"Android"

##八、调用云方法

有些逻辑是无法通过普通的增删改查数据来实现的,比如记录所有用户打开某界面的次数openCount。这时候,服务端通过提供"云端方法"即可解决这些问题。

假如为了解决上述问题,服务端提供了一个"addOpenCount"云方法,当客户端调用此方法的时候,服务端则会把openCount数量加1。

调用云方法的代码非常简单:

JBCloud.callFunctionInBackground("addOpenCount", null ,new CloudCallback() {
		@Override
		public void done(ResponseEntity responseEntity) {
			Log.d("ObjectTest", "调用成功 " + responseEntity.getMessage());
		}

		@Override
		public void error(JBException e, ResponseEntity responseEntity) {
			Log.d("ObjectTest", "调用失败 " + responseEntity.getMessage());
		}
});

有的时候调用云方法还需将参数传递上去,比如我们需要实现一个用户给某产品评分的需求,服务端提供一个"addProductScore"云方法,客户端就可以调用此方法并将所评的分数传上去。

代码如下:

HashMap<String, Object> params = new HashMap<>();
params.put("productScore",100);
        
JBCloud.callFunctionInBackground("addProductScore", params, new CloudCallback() {
		@Override
		public void done(ResponseEntity responseEntity) {
			Log.d("ObjectTest", "调用成功 " + responseEntity.getMessage());
		}

		@Override
		public void error(JBException e, ResponseEntity responseEntity) {
			Log.d("ObjectTest", "调用失败 " + responseEntity.getMessage());
		}
});

About

JavaBaas Android SDK.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages