HarmonyOS基础技术赋能之对象关系映射数据库的使用 原创 精华
引言
HarmonyOS对象关系映射(Object Relational Mapping,ORM)数据库是一款基于SQLite的数据库框架,屏蔽了底层SQLite数据库的SQL操作,针对实体和关系提供了增删改查等一系列的面向对象接口。应用开发者不必再去编写复杂的SQL语句, 以操作对象的形式来操作数据库,提升效率的同时也能聚焦于业务开发。
功能介绍
对象关系映射数据库目前可以支持数据库和表的创建,对象数据的增删改查、对象数据变化回调、数据库升降级和备份等功能。
开发指南
1. 配置“build.gradle”文件。
//在ohos节点中添加以下配置:
compileOptions{
annotationEnabled true
}
2. 构造数据库。
//例如,定义了一个数据库类BookStore.java,数据库包含了“User”一张表,版本号为“1”。数据库类的getVersion方法和getHelper方法不需要实现,直接将数据库类设为虚类即可。
@Database(entities = {User.class}, version = 1)
public abstract class BookStore extends OrmDatabase {
}
3.构造数据表。
//创建数据库实体类并配置对应的属性(如对应表的主键,外键等
@Entity(tableName = "user")
public class User extends OrmObject {
// 此处将userId设为了自增的主键。注意只有在数据类型为包装类型时,自增主键才能生效。
@PrimaryKey(autoGenerate = true)
private Integer userId;
private String userName;
private int userAge;
private String userRole;
public User() {
}
// 需添加各字段的getter和setter方法。
……
……
}
4. 使用对象数据操作接口OrmContext创建数据库。
// context入参类型为ohos.app.Context,注意不要使用slice.getContext()来获取context,请直接传入slice,否则会出现找不到类的报错。
DatabaseHelper helper = new DatabaseHelper(this);
OrmContext context = helper.getOrmContext("BookStore", "BookStore.db", BookStore.class);
5. 使用对象数据操作接口OrmContext对数据库进行增删改查、注册观察者、备份数据库等。
1)首先需要创建一个DataAbility. 右键项目包名→New→Ability→Empty Data Ability,点击进入configure Ability,然后自己定义Data Name,例如:UserDataAbilty。
2)然后在UserDataAbilty类中重写增删改查的方法:
//先在onstart()方法中创建OrmContext对象,context入参类型为ohos.app.Context,注意不要使用slice.getContext()来获取context,请直接传入slice,否则会出现找不到类的报错。
DatabaseHelper helper = new DatabaseHelper(this);
OrmContext context = helper.getOrmContext("BookStore", "BookStore.db", BookStore.class);
// 然后重新增删改查方法 query()/insert()/update()/delete()
@Override
public ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) {
if(ormContext == null){
HiLog.error(LABEL_LOG,"failed to query, ormContext is null");
return null;
}
//查询数据库
OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates, User.class);
ResultSet resultSet = ormContext.query(ormPredicates,columns);
if (resultSet == null){
HiLog.info(LABEL_LOG,"resultSet is null");
}
return resultSet;
}
@Override
public int insert(Uri uri, ValuesBucket value) {
// 参数校验
if (ormContext == null) {
HiLog.error(LABEL_LOG, "failed to insert, ormContext is null");
return -1;
}
// 构造插入数据
User user = new User();
user.setUserId(value.getInteger("userId"));
user.setUserName(value.getString("userName"));
user.setUserAge(value.getInteger("userAge"));
user.setUserRole(value.getString("userRole"));
// 插入数据库
boolean isSuccessed;
isSuccessed = ormContext.insert(user);
if (!isSuccessed) {
HiLog.error(LABEL_LOG, "failed to insert");
return -1;
}
isSuccessed = ormContext.flush();
if (!isSuccessed) {
HiLog.error(LABEL_LOG, "failed to insert flush");
return -1;
}
DataAbilityHelper.creator(this, uri).notifyChange(uri);
//返回的id,为数据表自增主键id
int id = Math.toIntExact(user.getRowId());
HiLog.debug(LABEL_LOG, "success to insert id="+id);
return id;
}
@Override
public int delete(Uri uri, DataAbilityPredicates predicates) {
if (ormContext == null) {
HiLog.error(LABEL_LOG, "failed to delete, ormContext is null");
return -1;
}
OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);
int result = ormContext.delete(ormPredicates);
DataAbilityHelper.creator(this, uri).notifyChange(uri);
// result>0 表示删除成功,result<=0 表示删除失败
if(result>0){
HiLog.debug(LABEL_LOG, "UserDataAbility success to delete value="+result);
}else {
HiLog.debug(LABEL_LOG, "UserDataAbility failed to delete value="+result);
}
return result;
}
@Override
public int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) {
if (ormContext == null) {
HiLog.error(LABEL_LOG, "failed to update, ormContext is null");
return -1;
}
OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);
int result = ormContext.update(ormPredicates, value);
// result>0 表示更新成功,result<=0 表示更新失败
if(result>0){
HiLog.info(LABEL_LOG, "UserDataAbility success to update value:" + result);
}else {
HiLog.info(LABEL_LOG, "UserDataAbility failed to update value:" + result);
}
DataAbilityHelper.creator(this, uri).notifyChange(uri);
return result;
}
6.在需要调用的地方,例如MainAbilitySlice中,先创建DataAbilityHelper 对象,然后调用DataAbilityHelper的增、删、改、查方法。
//创建DataAbilityHelper
DataAbilityHelper helper = DataAbilityHelper.creator(this);
//插入数据
//其中Uri uri = Uri.parse(String Uri);里面的配置字符串Uri就是用于读取关系映射数据库的路径,来自于创建DataAbility后,在config.json中的Uri标签,本案例中的String Uri= “dataability://com.isoftstone.ormdatebase.UserDataAbility”
helper.insert(uri, valuesBucket);
//删除数据
helper.delete(uri,predicates);
//修改数据
helper.update(uri, valuesBucket, predicates)
//查询数据
ResultSet resultSet = helper.query(uri, columns, predicates)
操作步骤
App打开之后:
1.点击QueryAll时,打印的log。(查询插入的“ZhangSan”、“LiSi”)
08-25 15:50:00.966 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: userId=1; userName=ZhangSan; userAge=22; userRole=teacher
08-25 15:50:00.967 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: userId=2; userName=LiSi; userAge=23; userRole=programmer
2.点击QueryByCondition时,打印的log。(条件查询“userRole=programmer”)
08-25 15:51:29.031 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: userId=2; userName=LiSi; userAge=23; userRole=programmer
3.点击Insert后,再点击QueryAll时,打印的log。(插入“WangWu”)
08-25 15:52:26.426 10496-10496/com.isoftstone.ormdatebase D 01100/Demo: success to insert id=3
08-25 15:52:31.466 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: userId=1; userName=ZhangSan; userAge=22; userRole=teacher
08-25 15:52:31.466 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: userId=2; userName=LiSi; userAge=23; userRole=programmer
08-25 15:52:31.467 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: userId=3; userName=WangWu; userAge=18; userRole=police
4.点击Update后,再点击QueryAll时,打印的log。(把“WangWu”修改为“ZhaoLiu”)
08-25 15:53:42.641 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: UserDataAbility success to update value:1
08-25 15:53:42.643 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: 1
08-25 15:54:35.062 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: userId=1; userName=ZhangSan; userAge=22; userRole=teacher
08-25 15:54:35.063 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: userId=2; userName=LiSi; userAge=23; userRole=programmer
08-25 15:54:35.063 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: userId=3; userName=ZhaoLiu; userAge=26; userRole=doctor
5.点击Delete后,在点击QueryAll时,打印的log。(删除“ZhaoLiu”)
08-25 15:55:26.885 10496-10496/com.isoftstone.ormdatebase D 01100/Demo: UserDataAbility success to delete value=1
08-25 15:55:29.157 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: userId=1; userName=ZhangSan; userAge=22; userRole=teacher
08-25 15:55:29.158 10496-10496/com.isoftstone.ormdatebase I 01100/Demo: userId=2; userName=LiSi; userAge=23; userRole=programmer
提供源码
1. BookStore
@Database(entities = {User.class}, version = 1)
public abstract class BookStore extends OrmDatabase {
}
2. User
@Entity(tableName = "user")
public class User extends OrmObject {
@PrimaryKey(autoGenerate = true)
private Integer userId;
private String userName;
private int userAge;
private String userRole;
public User() {
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUserAge() {
return userAge;
}
public void setUserAge(int userAge) {
this.userAge = userAge;
}
public String getUserRole() {
return userRole;
}
public void setUserRole(String userRole) {
this.userRole = userRole;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", userAge=" + userAge +
", userRole='" + userRole + '\'' +
'}';
}
}
3. UserDataAbility
public class UserDataAbility extends Ability {
private static final String DATABASE_NAME ="BookStore.db";
private static final String DATABASE_NAME_ALIAS = "BookStore";
private static OrmContext ormContext = null;
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "Demo");
@Override
public void onStart(Intent intent) {
super.onStart(intent);
DatabaseHelper helper = new DatabaseHelper(this);
ormContext = helper.getOrmContext(DATABASE_NAME_ALIAS, DATABASE_NAME, BookStore.class);
User user1 = new User();
user1.setUserName("ZhangSan");
user1.setUserAge(22);
user1.setUserRole("teacher");
ormContext.insert(user1);
User user2 = new User();
user2.setUserName("LiSi");
user2.setUserAge(23);
user2.setUserRole("programmer");
ormContext.insert(user2);
ormContext.flush();
}
@Override
public ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) {
if(ormContext == null){
HiLog.error(LABEL_LOG,"failed to query, ormContext is null");
return null;
}
//查询数据库
OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates, User.class);
ResultSet resultSet = ormContext.query(ormPredicates,columns);
if (resultSet == null){
HiLog.info(LABEL_LOG,"resultSet is null");
}
return resultSet;
}
@Override
public int insert(Uri uri, ValuesBucket value) {
// 参数校验
if (ormContext == null) {
HiLog.error(LABEL_LOG, "failed to insert, ormContext is null");
return -1;
}
// 构造插入数据
User user = new User();
user.setUserId(value.getInteger("userId"));
user.setUserName(value.getString("userName"));
user.setUserAge(value.getInteger("userAge"));
user.setUserRole(value.getString("userRole"));
// 插入数据库
boolean isSuccessed;
isSuccessed = ormContext.insert(user);
if (!isSuccessed) {
HiLog.error(LABEL_LOG, "failed to insert");
return -1;
}
isSuccessed = ormContext.flush();
if (!isSuccessed) {
HiLog.error(LABEL_LOG, "failed to insert flush");
return -1;
}
DataAbilityHelper.creator(this, uri).notifyChange(uri);
//返回的id,为数据表自增主键id
int id = Math.toIntExact(user.getRowId());
HiLog.debug(LABEL_LOG, "success to insert id="+id);
return id;
}
@Override
public int delete(Uri uri, DataAbilityPredicates predicates) {
if (ormContext == null) {
HiLog.error(LABEL_LOG, "failed to delete, ormContext is null");
return -1;
}
OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);
int result = ormContext.delete(ormPredicates);
DataAbilityHelper.creator(this, uri).notifyChange(uri);
// result>0 表示删除成功,result<=0 表示删除失败
if(result>0){
HiLog.debug(LABEL_LOG, "UserDataAbility success to delete value="+result);
}else {
HiLog.debug(LABEL_LOG, "UserDataAbility failed to delete value="+result);
}
return result;
}
@Override
public int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) {
if (ormContext == null) {
HiLog.error(LABEL_LOG, "failed to update, ormContext is null");
return -1;
}
OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);
int result = ormContext.update(ormPredicates, value);
// result>0 表示更新成功,result<=0 表示更新失败
if(result>0){
HiLog.info(LABEL_LOG, "UserDataAbility success to update value:" + result);
}else {
HiLog.info(LABEL_LOG, "UserDataAbility failed to update value:" + result);
}
DataAbilityHelper.creator(this, uri).notifyChange(uri);
return result;
}
}
4. MainAbilitySlice
public class MainAbilitySlice extends AbilitySlice implements ClickedListener {
private String uriString = "dataability:///com.isoftstone.ormdatebase.UserDataAbility";
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "Demo");
private DataAbilityHelper helper;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
helper = DataAbilityHelper.creator(this);
Button queryAll = (Button) findComponentById(ResourceTable.Id_query_all);
Button queryByCondition = (Button) findComponentById(ResourceTable.Id_query_by_condition);
Button insert = (Button) findComponentById(ResourceTable.Id_insert);
Button update = (Button) findComponentById(ResourceTable.Id_update);
Button delete = (Button) findComponentById(ResourceTable.Id_delete);
queryAll.setClickedListener(this);
queryByCondition.setClickedListener(this);
insert.setClickedListener(this);
update.setClickedListener(this);
delete.setClickedListener(this);
}
@Override
public void onClick(Component component) {
switch (component.getId()){
case ResourceTable.Id_query_all:
try {
queryAll();
} catch (Exception e) {
e.printStackTrace();
}
break;
case ResourceTable.Id_query_by_condition:
try {
queryByCondition();
} catch (Exception e) {
e.printStackTrace();
}
break;
case ResourceTable.Id_insert:
try {
insert();
} catch (Exception e) {
e.printStackTrace();
}
break;
case ResourceTable.Id_update:
try {
update();
} catch (Exception e) {
e.printStackTrace();
}
break;
case ResourceTable.Id_delete:
try {
delete();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void queryAll() throws DataAbilityRemoteException {
// 构造查询条件
DataAbilityPredicates predicates = new DataAbilityPredicates();
String[] columns = new String[]{"userId", "userName", "userAge", "userRole"};
Uri uri = Uri.parse(uriString);
ResultSet resultSet = helper.query(uri, columns, predicates);
// 处理结果
resultSet.goToFirstRow();
do {
// 在此处理ResultSet中的记录;
HiLog.info(LABEL_LOG,
"userId=" + resultSet.getString(0)
+ "; userName=" + resultSet.getString(1)
+ "; userAge=" + resultSet.getString(2)
+ "; userRole=" + resultSet.getString(3));
} while (resultSet.goToNextRow());
}
public void queryByCondition() throws DataAbilityRemoteException {
// 构造查询条件
DataAbilityPredicates predicates = new DataAbilityPredicates();
predicates.equalTo("userRole", "programmer");
String[] columns = new String[]{"userId", "userName", "userAge", "userRole"};
Uri uri = Uri.parse(uriString);
ResultSet resultSet = helper.query(uri, columns, predicates);
// 处理结果
resultSet.goToFirstRow();
do {
// 在此处理ResultSet中的记录;
HiLog.info(LABEL_LOG,
"userId=" + resultSet.getString(0)
+ "; userName=" + resultSet.getString(1)
+ "; userAge=" + resultSet.getString(2)
+ "; userRole=" + resultSet.getString(3));
} while (resultSet.goToNextRow());
}
public void insert() throws DataAbilityRemoteException {
DataAbilityHelper helper = DataAbilityHelper.creator(this);
Uri uri = Uri.parse(uriString);
ValuesBucket valuesBucket = new ValuesBucket();
valuesBucket.putString("userName", "WangWu");
valuesBucket.putInteger("userAge", 18);
valuesBucket.putString("userRole", "police");
helper.insert(uri, valuesBucket);
}
public void update() throws DataAbilityRemoteException {
// 构造插入数据
DataAbilityHelper helper = DataAbilityHelper.creator(this);
// 构造更新条件
DataAbilityPredicates predicates = new DataAbilityPredicates();
predicates.equalTo("userName", "WangWu");
// 构造更新数据
ValuesBucket valuesBucket = new ValuesBucket();
valuesBucket.putString("userName", "ZhaoLiu");
valuesBucket.putInteger("UserAge", 26);
valuesBucket.putString("userRole", "doctor");
Uri uri = Uri.parse(uriString);
int update = helper.update(uri, valuesBucket, predicates);
}
public void delete() throws DataAbilityRemoteException {
DataAbilityHelper helper = DataAbilityHelper.creator(this);
Uri uri = Uri.parse(uriString);
// 构造删除条件
DataAbilityPredicates predicates = new DataAbilityPredicates();
predicates.equalTo("userName", "ZhaoLiu");
helper.delete(uri,predicates);
}
}
5. 页面布局ability_main.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical" >
<Button
ohos:id="$+id:query_all"
ohos:width="match_content"
ohos:height="match_content"
ohos:text="QueryAll"
ohos:text_size="19fp"
ohos:text_color="#FFFFFF"
ohos:top_margin="30vp"
ohos:top_padding="8vp"
ohos:bottom_padding="8vp"
ohos:right_padding="70vp"
ohos:left_padding="70vp"
ohos:background_element="$graphic:background_button"
ohos:center_in_parent="true"
ohos:align_parent_bottom="true"
ohos:bottom_margin="40vp"
ohos:layout_alignment="center"
/>
<Button
ohos:id="$+id:query_by_condition"
ohos:width="match_content"
ohos:height="match_content"
ohos:text="queryByCondition"
ohos:text_size="19fp"
ohos:text_color="#FFFFFF"
ohos:top_padding="8vp"
ohos:bottom_padding="8vp"
ohos:right_padding="70vp"
ohos:left_padding="70vp"
ohos:background_element="$graphic:background_button"
ohos:center_in_parent="true"
ohos:align_parent_bottom="true"
ohos:bottom_margin="40vp"
ohos:layout_alignment="center"
/>
<Button
ohos:id="$+id:insert"
ohos:width="match_content"
ohos:height="match_content"
ohos:text="Insert"
ohos:text_size="19fp"
ohos:text_color="#FFFFFF"
ohos:top_padding="8vp"
ohos:bottom_padding="8vp"
ohos:right_padding="70vp"
ohos:left_padding="70vp"
ohos:background_element="$graphic:background_button"
ohos:center_in_parent="true"
ohos:align_parent_bottom="true"
ohos:bottom_margin="40vp"
ohos:layout_alignment="center"
/>
<Button
ohos:id="$+id:update"
ohos:width="match_content"
ohos:height="match_content"
ohos:text="Update"
ohos:text_size="19fp"
ohos:text_color="#FFFFFF"
ohos:top_padding="8vp"
ohos:bottom_padding="8vp"
ohos:right_padding="70vp"
ohos:left_padding="70vp"
ohos:background_element="$graphic:background_button"
ohos:center_in_parent="true"
ohos:align_parent_bottom="true"
ohos:bottom_margin="40vp"
ohos:layout_alignment="center"
/>
<Button
ohos:id="$+id:delete"
ohos:width="match_content"
ohos:height="match_content"
ohos:text="Delete"
ohos:text_size="19fp"
ohos:text_color="#FFFFFF"
ohos:top_padding="8vp"
ohos:bottom_padding="8vp"
ohos:right_padding="70vp"
ohos:left_padding="70vp"
ohos:background_element="$graphic:background_button"
ohos:center_in_parent="true"
ohos:align_parent_bottom="true"
ohos:bottom_margin="40vp"
ohos:layout_alignment="center"
/>
</DirectionalLayout>
6.圆角背景图形background_button.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="100"/>
<solid
ohos:color="#007DFF"/>
</shape>
7.config.json
{
"app": {
"bundleName": "com.isoftstone.ormdatebase",
"vendor": "isoftstone",
"version": {
"code": 1000000,
"name": "1.0"
},
"apiVersion": {
"compatible": 4,
"target": 5,
"releaseType": "Release"
}
},
"deviceConfig": {},
"module": {
"package": "com.isoftstone.ormdatebase",
"name": ".MyApplication",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry"
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"orientation": "unspecified",
"name": "com.isoftstone.ormdatebase.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:app_name",
"type": "page",
"launchType": "standard"
},
{
"visible": true,
"permissions": [
"com.isoftstone.ormdatebase.DataAbilityShellProvider.PROVIDER"
],
"name": "com.isoftstone.ormdatebase.UserDataAbility",
"icon": "$media:icon",
"description": "$string:userdataability_description",
"type": "data",
"uri": "dataability://com.isoftstone.ormdatebase.UserDataAbility"
}
]
}
}
8.build.gradle
apply plugin: 'com.huawei.ohos.hap'
ohos {
compileSdkVersion 5
defaultConfig {
compatibleSdkVersion 4
}
compileOptions{
annotationEnabled true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
testCompile 'junit:junit:4.12'
}
更多原创内容请关注:软通动力HarmonyOS学院
张老师更新的好快
张老师文章版面工整,内容详细
张老师加油
学习学习
张老师加油
感谢张老师分享
感谢张老师分享
太强了大佬
想请教老师,我运行项目的时候报IllegalStateException错误:java.lang.IllegalStateException: Execute getHelper failed : com.example.productdisplayapp.database.ProductInfoHelper。可能是什么引起的呢?照着您的代码写的:报错的完整信息:Device info:DBY-W09
Build info:DBY-W09 2.0.0.225(C00E210R1P13)
Module name:com.example.productdisplayapp
Version:1.0.0
Pid:19554
Uid:10231
Foreground:Yes
Reason:IllegalStateException
Selected stacktrace:
java.lang.IllegalStateException: Execute getHelper failed : com.example.productdisplayapp.database.ProductInfoHelper
at ohos.data.orm.impl.OrmStore.getHelper(OrmStore.java:304)
at ohos.data.orm.impl.OrmStore.createFromOrmPredicates(OrmStore.java:537)
at ohos.data.orm.impl.OrmStore.executeSharedFetchRequest(OrmStore.java:346)
at ohos.data.orm.impl.OrmContextImpl.query(OrmContextImpl.java:209)
at com.example.productdisplayapp.ProdInfoDataAbility.query(ProdInfoDataAbility.java:63)
at ohos.abilityshell.AbilityShellProviderDelegate.query(AbilityShellProviderDelegate.java:149)
at ohos.abilityshell.AbilityShellProvider.query(AbilityShellProvider.java:55)
at android.content.ContentProvider.query(ContentProvider.java:1218)
at android.content.ContentProvider.query(ContentProvider.java:1311)
at android.content.ContentProvider$Transport.query(ContentProvider.java:271)
at android.content.ContentProviderClient.query(ContentProviderClient.java:195)
at android.content.ContentProviderClient.query(ContentProviderClient.java:177)
at android.content.ContentProviderClient.query(ContentProviderClient.java:167)
at ohos.abilityshell.ApplicationDataAbility.query(ApplicationDataAbility.java:167)
at ohos.aafwk.ability.DataAbilityHelper.query(DataAbilityHelper.java:423)
at com.example.productdisplayapp.slice.MainAbilitySlice.initIndexImage(MainAbilitySlice.java:211)
at com.example.productdisplayapp.slice.MainAbilitySlice.initindex(MainAbilitySlice.java:140)
at com.example.productdisplayapp.slice.MainAbilitySlice.access$000(MainAbilitySlice.java:33)
at com.example.productdisplayapp.slice.MainAbilitySlice$1.onSelected(MainAbilitySlice.java:77)
at ohos.agp.components.TabList$TabListSelectionHandler.onTabSelectionChanged(TabList.java:294)
at ohos.agp.components.TabList.nativeTabLayoutTabSelect(Native Method)
at ohos.agp.components.TabList.access$100(TabList.java:38)
at ohos.agp.components.TabList$Tab.select(TabList.java:183)
at ohos.agp.components.TabList.selectTab(TabList.java:572)
at ohos.agp.components.TabList.selectTabAt(TabList.java:558)
at com.example.productdisplayapp.slice.MainAbilitySlice.onStart(MainAbilitySlice.java:108)
at ohos.aafwk.ability.AbilitySlice.start(AbilitySlice.java:3270)
at ohos.aafwk.ability.AbilitySliceScheduler.handleStartAbilitySlice(AbilitySliceScheduler.java:717)
at ohos.aafwk.ability.AbilitySliceManager.onAbilityStart(AbilitySliceManager.java:300)
at ohos.aafwk.ability.Ability.dispatchAbilityLifecycle(Ability.java:4579)
at ohos.aafwk.ability.Ability.start(Ability.java:3634)
at ohos.aafwk.ability.Ability.handleLifecycleTransaction(Ability.java:4751)
at ohos.aafwk.ability.Ability.scheduleAbilityLifecycle(Ability.java:1517)
at ohos.abilityshell.AbilityShellDelegate.scheduleAbilityLifecycle(AbilityShellDelegate.java:132)
at ohos.abilityshell.AbilityShellActivityDelegate.onStart(AbilityShellActivityDelegate.java:340)
at ohos.abilityshell.AbilityShellActivity.onStart(AbilityShellActivity.java:67)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1447)
at android.app.Activity.performStart(Activity.java:8237)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:4084)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:235)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:215)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:187)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2613)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8668)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)