├── .gitignore
├── .idea
├── gradle.xml
├── misc.xml
├── previewer
│ ├── phone
│ │ └── phoneSettingConfig_106113203.json
│ └── previewConfig.json
└── vcs.xml
├── build.gradle
├── entry
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── config.json
│ ├── java
│ └── com
│ │ └── istone
│ │ └── myapplication
│ │ ├── GifAbility.java
│ │ ├── HarmonyOS.java
│ │ ├── ListAbility.java
│ │ ├── LocalAbility.java
│ │ ├── MainAbility.java
│ │ ├── ResourcesChangeAbility.java
│ │ ├── ServerAbility.java
│ │ ├── adapter
│ │ └── TopicItemProvider.java
│ │ ├── domain
│ │ └── TopicDomain.java
│ │ ├── slice
│ │ ├── BAbilitySlice.java
│ │ ├── GifAbilitySlice.java
│ │ ├── ListAbilitySlice.java
│ │ ├── LocalAbilitySlice.java
│ │ ├── MainAbilitySlice.java
│ │ ├── ResourcesChangeAbilitySlice.java
│ │ └── ServerAbilitySlice.java
│ │ └── utils
│ │ └── LogUtils.java
│ └── resources
│ ├── base
│ ├── element
│ │ └── string.json
│ ├── graphic
│ │ ├── background_ability_gif.xml
│ │ ├── background_ability_list.xml
│ │ ├── background_ability_local.xml
│ │ ├── background_ability_main.xml
│ │ ├── background_ability_resources_change.xml
│ │ ├── background_ability_second.xml
│ │ └── background_ability_server.xml
│ ├── layout
│ │ ├── ability_gif.xml
│ │ ├── ability_list.xml
│ │ ├── ability_local.xml
│ │ ├── ability_main.xml
│ │ ├── ability_resources_change.xml
│ │ ├── ability_second.xml
│ │ ├── ability_server.xml
│ │ ├── ability_two.xml
│ │ └── list_item_layout.xml
│ └── media
│ │ ├── A.png
│ │ ├── B.jpg
│ │ └── icon.png
│ └── rawfile
│ ├── A.gif
│ └── A.png
├── glidelibrary
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── config.json
│ ├── java
│ └── com
│ │ └── isotne
│ │ └── glidelibrary
│ │ ├── FileType.java
│ │ ├── cache
│ │ ├── loader
│ │ │ └── CacheLoader.java
│ │ └── util
│ │ │ ├── CacheUtils.java
│ │ │ ├── DiskLruCache.java
│ │ │ ├── DiskLruCacheImpl.java
│ │ │ ├── DiskLruCacheUtil.java
│ │ │ ├── ImageUtils.java
│ │ │ ├── MemoryCacheUtil.java
│ │ │ ├── StrictLineReader.java
│ │ │ └── Utils.java
│ │ ├── constant
│ │ └── Constents.java
│ │ ├── gif
│ │ └── LoadGif.java
│ │ ├── interceptor
│ │ └── NetCacheInterceptor.java
│ │ ├── okhttp
│ │ └── OkHttpManager.java
│ │ └── utils
│ │ ├── LogUtils.java
│ │ └── OhosGlide.java
│ └── resources
│ └── base
│ ├── element
│ └── string.json
│ └── layout
│ └── ability_main.xml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
14 |
15 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/previewer/phone/phoneSettingConfig_106113203.json:
--------------------------------------------------------------------------------
1 | {
2 | "setting": {
3 | "1.0.1": {
4 | "Language": {
5 | "args": {
6 | "Language": "zh-CN"
7 | }
8 | }
9 | }
10 | },
11 | "frontend": {
12 | "1.0.0": {
13 | "Resolution": {
14 | "args": {
15 | "Resolution": "360*750"
16 | }
17 | },
18 | "DeviceType": {
19 | "args": {
20 | "DeviceType": "phone"
21 | }
22 | }
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/.idea/previewer/previewConfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "1.0.0": {
3 | "LastPreviewDevice": {
4 | "E:\\MyApplication\\entry": []
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | apply plugin: 'com.huawei.ohos.app'
3 |
4 | ohos {
5 | compileSdkVersion 4
6 | defaultConfig {
7 | compatibleSdkVersion 3
8 | }
9 | }
10 |
11 | buildscript {
12 | repositories {
13 | maven {
14 | url 'https://mirrors.huaweicloud.com/repository/maven/'
15 | }
16 | maven {
17 | url 'https://developer.huawei.com/repo/'
18 | }
19 | jcenter()
20 | }
21 | dependencies {
22 | classpath 'com.huawei.ohos:hap:2.4.1.4'
23 | }
24 | }
25 |
26 | allprojects {
27 | repositories {
28 | maven {
29 | url 'https://mirrors.huaweicloud.com/repository/maven/'
30 | }
31 | maven {
32 | url 'https://developer.huawei.com/repo/'
33 | }
34 | jcenter()
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/entry/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/entry/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.huawei.ohos.hap'
2 | ohos {
3 | signingConfigs {
4 | debug {
5 | storeFile file('D:/keystore.p12')
6 | storePassword '0000001C7688E2D7631C7D58FCC70E03015ECA5A955E6ADC78A7F0B119A36EEB6AAD3AD6C78D35BA70F7D2D1'
7 | keyAlias 'keystore'
8 | keyPassword '0000001C7E6B08B19B7DADEC085D2DA48449510520B84BD1DA40759BF553E0B74029FB8926E204A8619FE83D'
9 | signAlg 'SHA256withECDSA'
10 | profile file('D:/ohosGlideDebug.p7b')
11 | certpath file('D:/keystore.cer')
12 | }
13 | }
14 | compileSdkVersion 4
15 | defaultConfig {
16 | compatibleSdkVersion 3
17 | }
18 | }
19 |
20 | dependencies {
21 | implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
22 | testCompile'junit:junit:4.12'
23 | implementation project(path: ':glidelibrary')
24 | }
25 |
--------------------------------------------------------------------------------
/entry/src/main/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": {
3 | "bundleName": "com.istone.myapplication",
4 | "vendor": "istone",
5 | "version": {
6 | "code": 1,
7 | "name": "1.0"
8 | },
9 | "apiVersion": {
10 | "compatible": 3,
11 | "target": 4,
12 | "releaseType": "Beta1"
13 | }
14 | },
15 | "deviceConfig": {},
16 | "module": {
17 | "package": "com.istone.myapplication",
18 | "name": "com.istone.myapplication.HarmonyOS",
19 | "deviceType": [
20 | "phone"
21 | ],
22 | "distro": {
23 | "deliveryWithInstall": true,
24 | "moduleName": "entry",
25 | "moduleType": "entry"
26 | },
27 | "abilities": [
28 | {
29 | "skills": [
30 | {
31 | "entities": [
32 | "entity.system.home"
33 | ],
34 | "actions": [
35 | "action.system.home",
36 | "action.play",
37 | "action.goto.page"
38 | ]
39 | }
40 | ],
41 | "orientation": "unspecified",
42 | "name": "com.istone.myapplication.MainAbility",
43 | "icon": "$media:icon",
44 | "description": "$string:mainability_description",
45 | "label": "HarmonyOS",
46 | "type": "page",
47 | "launchType": "standard"
48 | },
49 | {
50 | "orientation": "unspecified",
51 | "name": "com.istone.myapplication.ResourcesChangeAbility",
52 | "icon": "$media:icon",
53 | "description": "$string:resourceschangeability_description",
54 | "label": "entry",
55 | "type": "page",
56 | "launchType": "standard"
57 | },
58 | {
59 | "orientation": "unspecified",
60 | "name": "com.istone.myapplication.ServerAbility",
61 | "icon": "$media:icon",
62 | "description": "$string:serverability_description",
63 | "label": "entry",
64 | "type": "page",
65 | "launchType": "standard"
66 | },
67 | {
68 | "orientation": "unspecified",
69 | "name": "com.istone.myapplication.LocalAbility",
70 | "icon": "$media:icon",
71 | "description": "$string:localability_description",
72 | "label": "entry",
73 | "type": "page",
74 | "launchType": "standard"
75 | },
76 | {
77 | "orientation": "unspecified",
78 | "name": "com.istone.myapplication.GifAbility",
79 | "icon": "$media:icon",
80 | "description": "$string:gifability_description",
81 | "label": "entry",
82 | "type": "page",
83 | "launchType": "standard"
84 | },
85 | {
86 | "orientation": "unspecified",
87 | "name": "com.istone.myapplication.ListAbility",
88 | "icon": "$media:icon",
89 | "description": "$string:listability_description",
90 | "label": "entry",
91 | "type": "page",
92 | "launchType": "standard"
93 | }
94 | ],
95 | "reqPermissions": [
96 | {
97 | "name": "ohos.permission.GET_NETWORK_INFO"
98 | },
99 | {
100 | "name": "ohos.permission.GET_WIFI_INFO"
101 | },
102 | {
103 | "name": "ohos.permission.INTERNET"
104 | },
105 | {
106 | "name": "ohos.permission.READ_MEDIA"
107 | },
108 | {
109 | "name": "ohos.permission.WRITE_MEDIA"
110 | },
111 | {
112 | "name": "ohos.permission.READ_USER_STORAGE"
113 | },
114 | {
115 | "name": "ohos.permission.WRITE_USER_STORAGE"
116 | },
117 | {
118 | "name": "ohos.permission.LOCATION"
119 | }
120 | ]
121 | }
122 | }
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/GifAbility.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication;
2 |
3 | import com.istone.myapplication.slice.GifAbilitySlice;
4 | import ohos.aafwk.ability.Ability;
5 | import ohos.aafwk.content.Intent;
6 |
7 | /**
8 | * description gif
9 | * @author baihe
10 | * created 2021/2/8 14:51
11 | */
12 | public class GifAbility extends Ability {
13 | @Override
14 | public void onStart(Intent intent) {
15 | super.onStart(intent);
16 | super.setMainRoute(GifAbilitySlice.class.getName());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/HarmonyOS.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication;
2 |
3 | import ohos.aafwk.ability.AbilityPackage;
4 |
5 | /**
6 | * description harmonyos
7 | * @author baihe
8 | * created 2021/2/8 14:51
9 | */
10 | public class HarmonyOS extends AbilityPackage {
11 | @Override
12 | public void onInitialize() {
13 |
14 | super.onInitialize();
15 |
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/ListAbility.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication;
2 |
3 | import com.istone.myapplication.slice.ListAbilitySlice;
4 | import ohos.aafwk.ability.Ability;
5 | import ohos.aafwk.content.Intent;
6 |
7 | /**
8 | * description list
9 | * @author baihe
10 | * created 2021/2/8 14:50
11 | */
12 | public class ListAbility extends Ability {
13 | @Override
14 | public void onStart(Intent intent) {
15 | super.onStart(intent);
16 | super.setMainRoute(ListAbilitySlice.class.getName());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/LocalAbility.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication;
2 |
3 | import com.istone.myapplication.slice.LocalAbilitySlice;
4 | import ohos.aafwk.ability.Ability;
5 | import ohos.aafwk.content.Intent;
6 |
7 | /**
8 | *description local
9 | *@author baihe
10 | *created 2021/2/8 14:52
11 | *
12 | */
13 | public class LocalAbility extends Ability {
14 | @Override
15 | public void onStart(Intent intent) {
16 | super.onStart(intent);
17 | super.setMainRoute(LocalAbilitySlice.class.getName());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/MainAbility.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication;
2 |
3 | import com.istone.myapplication.slice.BAbilitySlice;
4 | import com.istone.myapplication.slice.MainAbilitySlice;
5 | import ohos.aafwk.ability.Ability;
6 | import ohos.aafwk.content.Intent;
7 |
8 | /**
9 | * description main
10 | * @author baihe
11 | * created 2021/2/8 14:50
12 | */
13 | public class MainAbility extends Ability {
14 | @Override
15 | public void onStart(Intent intent) {
16 | super.onStart(intent);
17 | super.setMainRoute(MainAbilitySlice.class.getName());
18 | addActionRoute("action.goto.page", BAbilitySlice.class.getName());
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/ResourcesChangeAbility.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication;
2 |
3 | import com.istone.myapplication.slice.ResourcesChangeAbilitySlice;
4 | import ohos.aafwk.ability.Ability;
5 | import ohos.aafwk.content.Intent;
6 |
7 | /**
8 | * description resources
9 | * @author baihe
10 | * created 2021/2/8 14:51
11 | */
12 | public class ResourcesChangeAbility extends Ability {
13 | @Override
14 | public void onStart(Intent intent) {
15 | super.onStart(intent);
16 | super.setMainRoute(ResourcesChangeAbilitySlice.class.getName());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/ServerAbility.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication;
2 |
3 | import com.istone.myapplication.slice.ServerAbilitySlice;
4 | import ohos.aafwk.ability.Ability;
5 | import ohos.aafwk.content.Intent;
6 |
7 | /**
8 | * description server
9 | * @author baihe
10 | * created 2021/2/8 14:51
11 | */
12 | public class ServerAbility extends Ability {
13 | @Override
14 | public void onStart(Intent intent) {
15 | super.onStart(intent);
16 | super.setMainRoute(ServerAbilitySlice.class.getName());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/adapter/TopicItemProvider.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication.adapter;
2 |
3 | import com.isotne.glidelibrary.utils.LogUtils;
4 | import com.isotne.glidelibrary.utils.OhosGlide;
5 | import com.istone.myapplication.ResourceTable;
6 | import com.istone.myapplication.domain.TopicDomain;
7 | import ohos.aafwk.ability.AbilitySlice;
8 | import ohos.agp.components.Component;
9 | import ohos.agp.components.ComponentContainer;
10 | import ohos.agp.components.LayoutScatter;
11 | import ohos.agp.components.RecycleItemProvider;
12 | import ohos.agp.components.Text;
13 | import ohos.agp.components.Image;
14 | import java.io.IOException;
15 | import java.util.List;
16 |
17 | /**
18 | * description topicitem provider
19 | *
20 | * @author baihe
21 | * created 2021/2/8 14:53
22 | */
23 | public class TopicItemProvider extends RecycleItemProvider {
24 | /**
25 | * list
26 | */
27 | private List list;
28 | /**
29 | * slice
30 | */
31 | private AbilitySlice slice;
32 |
33 | public TopicItemProvider(List list, AbilitySlice slice) {
34 | // subcribeNetwork();
35 | this.list = list;
36 | this.slice = slice;
37 | }
38 |
39 | @Override
40 | public int getCount() {
41 | return list.size();
42 | }
43 |
44 | @Override
45 | public Object getItem(int position) {
46 | if (list != null && position > 0 && position < list.size()) {
47 | return list.get(position);
48 | }
49 | return null;
50 | }
51 |
52 | @Override
53 | public long getItemId(int position) {
54 | return position;
55 | }
56 |
57 | @Override
58 | public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
59 | Component cpt;
60 | ViewHolder viewHolder;
61 | LogUtils.log(LogUtils.ERROR,"abc=","===========33333");
62 | if (convertComponent == null) {
63 | cpt = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_list_item_layout, null, false);
64 | viewHolder = new ViewHolder();
65 | viewHolder.topic = (Text) cpt.findComponentById(ResourceTable.Id_topic);
66 | viewHolder.image = (Image) cpt.findComponentById(ResourceTable.Id_imageView);
67 | cpt.setTag(viewHolder);
68 | } else {
69 | cpt = convertComponent;
70 | viewHolder = (ViewHolder) cpt.getTag();
71 | }
72 |
73 | TopicDomain topic = list.get(position);
74 | viewHolder.topic.setText(topic.getTopic());
75 | try {
76 | OhosGlide.with(slice).load(topic.getUrl()).def(ResourceTable.Media_A).hasDiskCache(true).into(viewHolder.image);
77 | } catch (IOException e) {
78 | e.printStackTrace();
79 | }
80 |
81 | return cpt;
82 | }
83 |
84 | // private void subcribeNetwork(){
85 | // LogUtils.log(LogUtils.ERROR,"abc=","========22222222");
86 | // MatchingSkills matchingSkills = new MatchingSkills();
87 | // matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_WIFI_CONN_STATE); // 网络链接状态监听事件
88 | // matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_WIFI_P2P_STATE_CHANGED);
89 | // CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
90 | // WifiEventSubscriber subscriber = new WifiEventSubscriber(subscribeInfo);
91 | // try {
92 | // CommonEventManager.subscribeCommonEvent(subscriber);
93 | // publish();
94 | // } catch (RemoteException e) {
95 | // }
96 | // }
97 |
98 | // private void publish(){
99 | // try {
100 | // Intent intent = new Intent();
101 | // Operation operation = new Intent.OperationBuilder()
102 | // .build();
103 | // intent.setOperation(operation);
104 | // CommonEventData eventData = new CommonEventData(intent);
105 | // CommonEventManager.publishCommonEvent(eventData);
106 | // } catch (RemoteException e) {
107 | // }
108 | // }
109 |
110 | /**
111 | * viewholder
112 | */
113 | class ViewHolder {
114 | /**
115 | * topic
116 | */
117 | private Text topic;
118 | /**
119 | * image
120 | */
121 | private Image image;
122 |
123 | /**
124 | * @return topic
125 | */
126 | public Text getTopic() {
127 | return topic;
128 | }
129 |
130 | /**
131 | * @param topic topic text
132 | */
133 | public void setTopic(Text topic) {
134 | this.topic = topic;
135 | }
136 |
137 | /**
138 | * @return iamge
139 | */
140 | public Image getImage() {
141 | return image;
142 | }
143 |
144 | /**
145 | * @param image image
146 | */
147 | public void setImage(Image image) {
148 | this.image = image;
149 | }
150 | }
151 |
152 | // class WifiEventSubscriber extends CommonEventSubscriber {
153 | // EventRunner runner = EventRunner.create(true);
154 | //
155 | // public WifiEventSubscriber(CommonEventSubscribeInfo subscribeInfo) {
156 | // super(subscribeInfo);
157 | // }
158 | //
159 | // @Override
160 | // public void onReceiveEvent(CommonEventData commonEventData) {
161 | // LogUtils.log(LogUtils.ERROR, "abc=", "======================");
162 | // // 待执行的操作,由开发者定义
163 | // MyEventHandler myHandler = new MyEventHandler(runner);
164 | // InnerEvent innerEvent = InnerEvent.get();
165 | // myHandler.sendEvent(innerEvent, 0, EventHandler.Priority.IMMEDIATE);
166 | //
167 | //// NetManager netManager = NetManager.getInstance(null);
168 | ////
169 | //// if (!netManager.hasDefaultNet()) {
170 | //// return;
171 | //// } else {
172 | ////// EventRunner runner = EventRunner.create(false);
173 | ////// MyEventHandler myHandler = new MyEventHandler(runner);
174 | ////// InnerEvent innerEvent = InnerEvent.get();
175 | ////// myHandler.sendEvent(innerEvent);
176 | //// }
177 | //
178 | //// if (WifiEvents.EVENT_ACTIVE_STATE.equals(commonEventData.getIntent().getAction())) {
179 | //// // 获取附带参数
180 | //// IntentParams params = commonEventData.getIntent().getParams();
181 | //// if (params == null) {
182 | //// return;
183 | //// }
184 | //// int wifiState = (int) params.getParam(WifiEvents.PARAM_ACTIVE_STATE);
185 | ////
186 | //// if (wifiState == WifiEvents.STATE_ACTIVE) { // 处理WLAN被打开消息
187 | //// } else if (wifiState == WifiEvents.STATE_INACTIVE) { // 处理WLAN被关闭消息
188 | //// } else { // 处理WLAN异常状态
189 | //// }
190 | //// }
191 | // }
192 | // }
193 | //
194 | // public class MyEventHandler extends EventHandler {
195 | // public MyEventHandler(EventRunner runner) {
196 | // super(runner);
197 | // }
198 | // // 重写实现processEvent方法
199 | // @Override
200 | // public void processEvent(InnerEvent event) {
201 | // super.processEvent(event);
202 | //
203 | // notifyDataChanged();
204 | //
205 | //
206 | // }
207 | // }
208 | }
209 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/domain/TopicDomain.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication.domain;
2 |
3 |
4 | /**
5 | * description list domain
6 | *
7 | * @author baihe
8 | * created 2021/2/8 14:37
9 | */
10 | public class TopicDomain {
11 | /**
12 | * topic
13 | */
14 | private String topic;
15 | /**
16 | * url
17 | */
18 | private String url;
19 |
20 | public TopicDomain(String topic, String url) {
21 | this.topic = topic;
22 | this.url = url;
23 |
24 | }
25 |
26 | public String getTopic() {
27 | return topic;
28 | }
29 |
30 | public void setTopic(String topic) {
31 | this.topic = topic;
32 | }
33 |
34 | public String getUrl() {
35 | return url;
36 | }
37 |
38 | public void setUrl(String url) {
39 | this.url = url;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/slice/BAbilitySlice.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication.slice;
2 |
3 | import com.istone.myapplication.ResourceTable;
4 | import ohos.aafwk.ability.AbilitySlice;
5 | import ohos.aafwk.content.Intent;
6 |
7 | /**
8 | * description resourcesslice
9 | *
10 | * @author baihe
11 | * created 2021/2/8 14:52
12 | */
13 | public class BAbilitySlice extends AbilitySlice {
14 |
15 | @Override
16 | public void onStart(Intent intent) {
17 | super.onStart(intent);
18 | super.setUIContent(ResourceTable.Layout_ability_resources_change);
19 |
20 | }
21 |
22 | @Override
23 | public void onActive() {
24 | super.onActive();
25 | }
26 |
27 | @Override
28 | public void onForeground(Intent intent) {
29 | super.onForeground(intent);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/slice/GifAbilitySlice.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication.slice;
2 |
3 | import com.isotne.glidelibrary.utils.OhosGlide;
4 | import com.istone.myapplication.ResourceTable;
5 | import ohos.aafwk.ability.AbilitySlice;
6 | import ohos.aafwk.content.Intent;
7 | import ohos.agp.components.Image;
8 |
9 | import java.io.IOException;
10 |
11 | /**
12 | * description gifslice
13 | * @author baihe
14 | * created 2021/2/8 14:53
15 | */
16 | public class GifAbilitySlice extends AbilitySlice {
17 | @Override
18 | public void onStart(Intent intent) {
19 | super.onStart(intent);
20 | super.setUIContent(ResourceTable.Layout_ability_gif);
21 | Image image = (Image) findComponentById(ResourceTable.Id_gif_image);
22 | try {
23 | OhosGlide.with(this).load("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang" +
24 | ".com%2Fuploads%2Fitem%2F201611%2F04%2F20161104110413_XzVAk.thumb.700_0" +
25 | ".gif&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999," +
26 | "10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614137486&t=ad88afe8f35232022db6009e8a165889").def(ResourceTable.Media_A).into(image);
27 | } catch (IOException e) {
28 | e.printStackTrace();
29 | }
30 | }
31 |
32 | @Override
33 | public void onActive() {
34 | super.onActive();
35 | }
36 |
37 | @Override
38 | public void onForeground(Intent intent) {
39 | super.onForeground(intent);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/slice/ListAbilitySlice.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication.slice;
2 |
3 | import com.istone.myapplication.ResourceTable;
4 | import com.istone.myapplication.adapter.TopicItemProvider;
5 | import com.istone.myapplication.domain.TopicDomain;
6 | import ohos.aafwk.ability.AbilitySlice;
7 | import ohos.aafwk.content.Intent;
8 | import ohos.agp.components.ListContainer;
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | /**
13 | * description listslice
14 | *
15 | * @author baihe
16 | * created 2021/2/8 14:53
17 | */
18 | public class ListAbilitySlice extends AbilitySlice {
19 | @Override
20 | public void onStart(Intent intent) {
21 | super.onStart(intent);
22 | super.setUIContent(ResourceTable.Layout_ability_list);
23 | initListContainer();
24 | }
25 |
26 | /**
27 | * initListContainer
28 | */
29 | private void initListContainer() {
30 | ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_container);
31 | List list = getData();
32 | TopicItemProvider sampleItemProvider = new TopicItemProvider(list, this);
33 | listContainer.setItemProvider(sampleItemProvider);
34 | }
35 |
36 | /**
37 | *
38 | * @return ArrayList
39 | */
40 | private ArrayList getData() {
41 | ArrayList list = new ArrayList<>();
42 |
43 | list.add(new TopicDomain("hello,1", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa2.att.hudong" +
44 | ".com%2F86%2F10%2F01300000184180121920108394217.jpg&refer=http%3A%2F%2Fa2.att.hudong" +
45 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
46 | "=8bbec0d30e98bdd5d5fdea87628554da"));
47 | list.add(new TopicDomain("hello,2", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa3.att.hudong" +
48 | ".com%2F65%2F38%2F16300534049378135355388981738.jpg&refer=http%3A%2F%2Fa3.att.hudong" +
49 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
50 | "=d27e0975ecff17c5ce14fa8494fb0733"));
51 | list.add(new TopicDomain("hello,3", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa3.att.hudong" +
52 | ".com%2F35%2F34%2F19300001295750130986345801104.jpg&refer=http%3A%2F%2Fa3.att.hudong" +
53 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
54 | "=555f2ca5b1b68279c47be3efab31efdc"));
55 | list.add(new TopicDomain("hello,4", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi2.w.yun.hjfile" +
56 | ".cn%2Fdoc%2F201303%2Fd5547c74-d9ad-4625-bd93-41c2817f1dff_03.jpg&refer=http%3A%2F%2Fi2.w.yun.hjfile" +
57 | ".cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
58 | "=b3454729f39611ac36cde849c02c2a7a"));
59 | list.add(new TopicDomain("hello,5", "https://ss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item" +
60 | "/9c16fdfaaf51f3de9ba8ee1194eef01f3a2979a8.jpg"));
61 | list.add(new TopicDomain("hello,6", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa1.att.hudong" +
62 | ".com%2F81%2F71%2F01300000164151121808718718556.jpg&refer=http%3A%2F%2Fa1.att.hudong" +
63 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
64 | "=de1cc282c8911a5c5fc2ffb9523bca16"));
65 | list.add(new TopicDomain("hello,7", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa3.att.hudong" +
66 | ".com%2F61%2F98%2F01300000248068123885985729957.jpg&refer=http%3A%2F%2Fa3.att.hudong" +
67 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
68 | "=50a9dc20e962e5b8464c6cc3525e6e20"));
69 | list.add(new TopicDomain("hello,8", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.aiimg" +
70 | ".com%2Fuploads%2Fuserup%2F0909%2F2Z64022L38.jpg&refer=http%3A%2F%2Fimg.aiimg" +
71 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
72 | "=e56a3b4c167d619173aaa77a1b33cf48"));
73 | list.add(new TopicDomain("hello,9", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa4.att.hudong" +
74 | ".com%2F63%2F70%2F06300000046969120433706514748.jpg&refer=http%3A%2F%2Fa4.att.hudong" +
75 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
76 | "=4bdcf09101945fd4f78fdf943dc886dc"));
77 | list.add(new TopicDomain("hello,10", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa3.att.hudong" +
78 | ".com%2F02%2F38%2F01300000237560123245382609951.jpg&refer=http%3A%2F%2Fa3.att.hudong" +
79 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
80 | "=13dec1ea4bae058c49ec0f28281445f9"));
81 | list.add(new TopicDomain("hello,11", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa2.att.hudong" +
82 | ".com%2F42%2F31%2F01300001320894132989315766618.jpg&refer=http%3A%2F%2Fa2.att.hudong" +
83 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
84 | "=96a6896fae35450377ec81ea19a09a1f"));
85 | list.add(new TopicDomain("hello,12", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic25.nipic" +
86 | ".com%2F20121107%2F8847866_164210379199_2.jpg&refer=http%3A%2F%2Fpic25.nipic.com&app=2002&size=f9999," +
87 | "10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t=b535ad3cac3cfaf5ebcab0cb4c987dd7"));
88 | list.add(new TopicDomain("hello,13", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic16.nipic" +
89 | ".com%2F20110928%2F5200151_002314030000_2.jpg&refer=http%3A%2F%2Fpic16.nipic.com&app=2002&size=f9999," +
90 | "10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t=e37c1cca646f0ccc773ade0fbe007b29"));
91 | list.add(new TopicDomain("hello,14", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa4.att.hudong" +
92 | ".com%2F43%2F83%2F01300000241358124822839175242.jpg&refer=http%3A%2F%2Fa4.att.hudong" +
93 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
94 | "=18a0ca4b0c1efd6a1bd5cb9760128060"));
95 | list.add(new TopicDomain("hello,15", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa0.att.hudong" +
96 | ".com%2F65%2F07%2F01300000204202121839075492554.jpg&refer=http%3A%2F%2Fa0.att.hudong" +
97 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
98 | "=cd1f8cc3f7114cd2a5453a6d34cb83e5"));
99 | list.add(new TopicDomain("hello,16", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa2.att.hudong" +
100 | ".com%2F14%2F68%2F19300001338674131496682910142.jpg&refer=http%3A%2F%2Fa2.att.hudong" +
101 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
102 | "=7d2fffd5d8565abd0ec6653681047631"));
103 | list.add(new TopicDomain("hello,17", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa2.att.hudong" +
104 | ".com%2F06%2F02%2F19300534106437134465026151672.jpg&refer=http%3A%2F%2Fa2.att.hudong" +
105 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
106 | "=c44578bae5bc4cdb90453804ad07f25f"));
107 | list.add(new TopicDomain("hello,18", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa2.att.hudong" +
108 | ".com%2F50%2F71%2F01300000240273131339713219664.jpg&refer=http%3A%2F%2Fa2.att.hudong" +
109 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
110 | "=5a3e158a0210c9eb5a47d0901b46bede"));
111 | list.add(new TopicDomain("hello,19", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa3.att.hudong" +
112 | ".com%2F45%2F36%2F14300000491308128107360639165.jpg&refer=http%3A%2F%2Fa3.att.hudong" +
113 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
114 | "=628a23b650920999e2f4c5987d1362a9"));
115 | list.add(new TopicDomain("hello,20", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa3.att.hudong" +
116 | ".com%2F13%2F41%2F01300000201800122190411861466.jpg&refer=http%3A%2F%2Fa3.att.hudong" +
117 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
118 | "=b90979078e62ebf9b549d19e726e18f0"));
119 | list.add(new TopicDomain("hello,21", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa4.att.hudong" +
120 | ".com%2F25%2F10%2F01300473586198134027108433788.jpg&refer=http%3A%2F%2Fa4.att.hudong" +
121 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
122 | "=42ba823236600a0f3b38fa049eb1048f"));
123 | list.add(new TopicDomain("hello,22", "https://ss3.baidu.com/9fo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item" +
124 | "/42166d224f4a20a4b44741a690529822720ed072.jpg"));
125 | list.add(new TopicDomain("hello,23", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbbs.jooyoo" +
126 | ".net%2Fattachment%2FMon_0910%2F24_293205_2d4adfacccd3031.jpg&refer=http%3A%2F%2Fbbs.jooyoo" +
127 | ".net&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
128 | "=a9a3fd7321f526fce2efbc3f9ca12691"));
129 | list.add(new TopicDomain("hello,24", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa1.att.hudong" +
130 | ".com%2F57%2F92%2F01300542193590138063924441627.jpg&refer=http%3A%2F%2Fa1.att.hudong" +
131 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
132 | "=e70284b49966a7ed68dd66dc61f2265b"));
133 | list.add(new TopicDomain("hello,25", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa4.att.hudong" +
134 | ".com%2F20%2F39%2F01300542519189139990390839214.jpg&refer=http%3A%2F%2Fa4.att.hudong" +
135 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
136 | "=8872f9316d250b09c62bdaac4b0f39fd"));
137 | list.add(new TopicDomain("hello,26", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa3.att.hudong" +
138 | ".com%2F08%2F22%2F01300000013945118822221353308.jpg&refer=http%3A%2F%2Fa3.att.hudong" +
139 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
140 | "=c342b96383bf760f3850c6aab89ae44c"));
141 | list.add(new TopicDomain("hello,27", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa2.att.hudong" +
142 | ".com%2F12%2F87%2F01300001149956130041875096065.jpg&refer=http%3A%2F%2Fa2.att.hudong" +
143 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
144 | "=1c2d14c12c3fdbb784cfc4faedcbd21b"));
145 | list.add(new TopicDomain("hello,28", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa3.att.hudong" +
146 | ".com%2F92%2F04%2F01000000000000119090475560392.jpg&refer=http%3A%2F%2Fa3.att.hudong" +
147 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
148 | "=de7a697e58b7d9973f53641042b24633"));
149 | list.add(new TopicDomain("hello,29", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa2.att.hudong" +
150 | ".com%2F11%2F48%2F01300000195282124296481807051.jpg&refer=http%3A%2F%2Fa2.att.hudong" +
151 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819582&t" +
152 | "=7cfffaaed1cb61482d00de24ac3caa41"));
153 | list.add(new TopicDomain("hello,30", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa3.att.hudong" +
154 | ".com%2F03%2F88%2F01300000400534127693880874175.jpg&refer=http%3A%2F%2Fa3.att.hudong" +
155 | ".com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614819998&t" +
156 | "=697fb067f33484da214a584bf9d4cf48"));
157 |
158 | return list;
159 | }
160 |
161 | @Override
162 | public void onActive() {
163 | super.onActive();
164 | }
165 |
166 | @Override
167 | public void onForeground(Intent intent) {
168 | super.onForeground(intent);
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/slice/LocalAbilitySlice.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication.slice;
2 |
3 | import com.isotne.glidelibrary.utils.OhosGlide;
4 | import com.istone.myapplication.ResourceTable;
5 | import ohos.aafwk.ability.AbilitySlice;
6 | import ohos.aafwk.content.Intent;
7 | import ohos.agp.components.Image;
8 | import ohos.app.Environment;
9 |
10 | import java.io.File;
11 | import java.io.FileInputStream;
12 | import java.io.FileNotFoundException;
13 | import java.io.InputStream;
14 | import java.io.IOException;
15 |
16 |
17 | /**
18 | * description localslice
19 | * @author baihe
20 | * created 2021/2/8 14:52
21 | */
22 | public class LocalAbilitySlice extends AbilitySlice {
23 | @Override
24 | public void onStart(Intent intent) {
25 | super.onStart(intent);
26 | super.setUIContent(ResourceTable.Layout_ability_local);
27 | Image image = (Image) findComponentById(ResourceTable.Id_local_image);
28 | File file = new File(this.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath(), "test.png");
29 | InputStream inputStream = null;
30 | try {
31 | inputStream = new FileInputStream(file);
32 | } catch (FileNotFoundException e) {
33 | e.printStackTrace();
34 | }
35 | try {
36 | OhosGlide.with(this).load(inputStream).def(ResourceTable.Media_B).into(image);
37 | } catch (IOException e) {
38 | e.printStackTrace();
39 | }
40 | }
41 |
42 |
43 | @Override
44 | public void onActive() {
45 | super.onActive();
46 | }
47 |
48 | @Override
49 | public void onForeground(Intent intent) {
50 | super.onForeground(intent);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/slice/MainAbilitySlice.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication.slice;
2 |
3 | import com.istone.myapplication.ResourceTable;
4 | import ohos.aafwk.ability.AbilitySlice;
5 | import ohos.aafwk.content.Intent;
6 | import ohos.agp.components.Button;
7 |
8 |
9 | /**
10 | * description mainslice
11 | *
12 | * @author baihe
13 | * created 2021/2/8 14:52
14 | */
15 | public class MainAbilitySlice extends AbilitySlice {
16 | @Override
17 | public void onStart(Intent intent) {
18 | super.onStart(intent);
19 | super.setUIContent(ResourceTable.Layout_ability_main);
20 | requestPermissionsFromUser(
21 | new String[]{"ohos.permission.READ_MEDIA", "ohos.permission.WRITE_MEDIA", "ohos.permission" +
22 | ".READ_USER_STORAGE", "ohos.permission.WRITE_USER_STORAGE",}, 0);
23 |
24 | Button button1 = (Button) findComponentById(ResourceTable.Id_change_local_button);
25 | button1.setClickedListener(component -> {
26 | Intent intent2 = new Intent();
27 | present(new ResourcesChangeAbilitySlice(), new Intent());
28 | });
29 |
30 | Button button2 = (Button) findComponentById(ResourceTable.Id_show_server_button);
31 | button2.setClickedListener(component -> {
32 |
33 | present(new ServerAbilitySlice(), new Intent());
34 | });
35 |
36 | Button button3 = (Button) findComponentById(ResourceTable.Id_show_local_button);
37 | button3.setClickedListener(component -> {
38 | present(new LocalAbilitySlice(), new Intent());
39 | });
40 |
41 | Button button4 = (Button) findComponentById(ResourceTable.Id_show_gif_button);
42 | button4.setClickedListener(component -> {
43 | present(new GifAbilitySlice(), new Intent());
44 | });
45 |
46 | Button button5 = (Button) findComponentById(ResourceTable.Id_disk_cache_button);
47 | button5.setClickedListener(component -> {
48 | present(new ListAbilitySlice(), new Intent());
49 | });
50 | }
51 |
52 | @Override
53 | public void onActive() {
54 | super.onActive();
55 | }
56 |
57 | @Override
58 | public void onForeground(Intent intent) {
59 | super.onForeground(intent);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/slice/ResourcesChangeAbilitySlice.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication.slice;
2 |
3 | import com.istone.myapplication.ResourceTable;
4 | import ohos.aafwk.ability.AbilitySlice;
5 | import ohos.aafwk.content.Intent;
6 | import ohos.agp.components.Button;
7 | import ohos.agp.components.Image;
8 |
9 | /**
10 | * description resourcesslice
11 | * @author baihe
12 | * created 2021/2/8 14:52
13 | */
14 | public class ResourcesChangeAbilitySlice extends AbilitySlice {
15 | /**
16 | * istrue
17 | */
18 | private boolean isTrue = true;
19 |
20 | @Override
21 | public void onStart(Intent intent) {
22 | super.onStart(intent);
23 | super.setUIContent(ResourceTable.Layout_ability_resources_change);
24 | Image image = (Image) findComponentById(ResourceTable.Id_resources_change_image);
25 | Button button = (Button) findComponentById(ResourceTable.Id_resources_change_button);
26 | button.setClickedListener(component -> {
27 | image.setPixelMap(isTrue ? ResourceTable.Media_A : ResourceTable.Media_B);
28 | isTrue = !isTrue;
29 | });
30 | }
31 |
32 | @Override
33 | public void onActive() {
34 | super.onActive();
35 | }
36 |
37 | @Override
38 | public void onForeground(Intent intent) {
39 | super.onForeground(intent);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/slice/ServerAbilitySlice.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication.slice;
2 |
3 | import com.isotne.glidelibrary.utils.OhosGlide;
4 | import com.istone.myapplication.ResourceTable;
5 | import ohos.aafwk.ability.AbilitySlice;
6 | import ohos.aafwk.content.Intent;
7 | import ohos.agp.components.Image;
8 |
9 | import java.io.IOException;
10 |
11 | /**
12 | * description serverslice
13 | * @author baihe
14 | * created 2021/2/8 14:52
15 | */
16 | public class ServerAbilitySlice extends AbilitySlice {
17 | @Override
18 | public void onStart(Intent intent) {
19 | super.onStart(intent);
20 | super.setUIContent(ResourceTable.Layout_ability_server);
21 | Image image = (Image) findComponentById(ResourceTable.Id_server_image);
22 | try {
23 | OhosGlide.with(this).load("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.wallcoo" +
24 | ".com%2Fnature%2Fda_ps_landscape_01%2Fwallpapers%2F1280x1024%2F%5Bwallcoo_com%5D_1" +
25 | ".jpg&refer=http%3A%2F%2Fwww.wallcoo.com&app=2002&size=f9999," +
26 | "10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614218186&t=37efae92a69da2fe7685a2813ad36b50").def(ResourceTable.Media_A).into(image);
27 | } catch (IOException e) {
28 | e.printStackTrace();
29 | }
30 | }
31 |
32 | @Override
33 | public void onActive() {
34 | super.onActive();
35 | }
36 |
37 | @Override
38 | public void onForeground(Intent intent) {
39 | super.onForeground(intent);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/entry/src/main/java/com/istone/myapplication/utils/LogUtils.java:
--------------------------------------------------------------------------------
1 | package com.istone.myapplication.utils;
2 |
3 | import ohos.hiviewdfx.HiLog;
4 | import ohos.hiviewdfx.HiLogLabel;
5 |
6 | /**
7 | * description logutil
8 | *
9 | * @author baihe
10 | * created 2021/2/8 14:52
11 | */
12 | public class LogUtils {
13 | /**
14 | * info
15 | */
16 | public static final int INFO = 0;
17 | /**
18 | * error
19 | */
20 | public static final int ERROR = 1;
21 | /**
22 | * debug
23 | */
24 | public static final int DEBUG = 2;
25 | /**
26 | * warning
27 | */
28 | public static final int WARN = 3;
29 |
30 | /**
31 | * @param logType LogUtils.INFO || LogUtils.ERROR || LogUtils.DEBUG|| LogUtils.WARN
32 | * @param tag 日志标识 根据喜好,自定义
33 | * @param message 需要打印的日志信息
34 | */
35 | public static void log(int logType, String tag, String message) {
36 | HiLogLabel lable = new HiLogLabel(HiLog.LOG_APP, 0x0, tag);
37 | switch (logType) {
38 | case INFO:
39 | HiLog.info(lable, message);
40 | break;
41 | case ERROR:
42 | HiLog.error(lable, message);
43 | break;
44 | case DEBUG:
45 | HiLog.debug(lable, message);
46 | break;
47 | case WARN:
48 | HiLog.warn(lable, message);
49 | break;
50 | default:
51 | break;
52 |
53 | }
54 | }
55 |
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/element/string.json:
--------------------------------------------------------------------------------
1 | {
2 | "string": [
3 | {
4 | "name": "app_name",
5 | "value": "MyApplication"
6 | },
7 | {
8 | "name": "mainability_description",
9 | "value": "Java_Phone_Empty Feature Ability"
10 | },
11 | {
12 | "name": "otherability_descrition",
13 | "value": "otherability_descrition"
14 | },
15 | {
16 | "name": "main_button_text",
17 | "value": "Switch Images"
18 | },
19 | {
20 | "name": "main_button_text2",
21 | "value": "Show Server Image"
22 | },
23 | {
24 | "name": "secondability_description",
25 | "value": "Java_Phone_Empty Feature Ability"
26 | },
27 | {
28 | "name": "main_button_text3",
29 | "value": "Show Local Image"
30 | },
31 | {
32 | "name": "resourceschangeability_description",
33 | "value": "hap sample empty provider"
34 | },
35 | {
36 | "name": "resourceschangeability_description",
37 | "value": "Java_Phone_Empty Feature Ability"
38 | },
39 | {
40 | "name": "serverability_description",
41 | "value": "Java_Phone_Empty Feature Ability"
42 | },
43 | {
44 | "name": "localability_description",
45 | "value": "Java_Phone_Empty Feature Ability"
46 | },
47 | {
48 | "name": "gifability_description",
49 | "value": "Java_Phone_Empty Feature Ability"
50 | },
51 | {
52 | "name": "listability_description",
53 | "value": "Java_Phone_Empty Feature Ability"
54 | }
55 | ]
56 | }
--------------------------------------------------------------------------------
/entry/src/main/resources/base/graphic/background_ability_gif.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/graphic/background_ability_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/graphic/background_ability_local.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/graphic/background_ability_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/graphic/background_ability_resources_change.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/graphic/background_ability_second.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/graphic/background_ability_server.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/layout/ability_gif.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/layout/ability_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/layout/ability_local.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/layout/ability_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
30 |
31 |
42 |
43 |
44 |
54 |
55 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/layout/ability_resources_change.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
16 |
28 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/layout/ability_second.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/layout/ability_server.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/layout/ability_two.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/layout/list_item_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
16 |
21 |
25 |
--------------------------------------------------------------------------------
/entry/src/main/resources/base/media/A.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isoftstone-dev/Gilde_HarmonyOS/ac12c5008fc5ccd2245fd303db3f7a0da39bb435/entry/src/main/resources/base/media/A.png
--------------------------------------------------------------------------------
/entry/src/main/resources/base/media/B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isoftstone-dev/Gilde_HarmonyOS/ac12c5008fc5ccd2245fd303db3f7a0da39bb435/entry/src/main/resources/base/media/B.jpg
--------------------------------------------------------------------------------
/entry/src/main/resources/base/media/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isoftstone-dev/Gilde_HarmonyOS/ac12c5008fc5ccd2245fd303db3f7a0da39bb435/entry/src/main/resources/base/media/icon.png
--------------------------------------------------------------------------------
/entry/src/main/resources/rawfile/A.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isoftstone-dev/Gilde_HarmonyOS/ac12c5008fc5ccd2245fd303db3f7a0da39bb435/entry/src/main/resources/rawfile/A.gif
--------------------------------------------------------------------------------
/entry/src/main/resources/rawfile/A.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isoftstone-dev/Gilde_HarmonyOS/ac12c5008fc5ccd2245fd303db3f7a0da39bb435/entry/src/main/resources/rawfile/A.png
--------------------------------------------------------------------------------
/glidelibrary/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/glidelibrary/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.huawei.ohos.library'
2 | ohos {
3 | compileSdkVersion 4
4 | defaultConfig {
5 | compatibleSdkVersion 4
6 | }
7 |
8 | }
9 |
10 | dependencies {
11 | implementation fileTree(dir: 'libs', include: ['*.jar'])
12 | implementation 'com.squareup.okhttp3:okhttp:4.4.0'
13 | implementation 'com.github.bumptech.glide:glide:4.4.0'
14 | annotationProcessor 'com.github.bumptech.glide:compiler:4.4.0'
15 | implementation 'com.jakewharton:disklrucache:2.0.2'
16 | testCompile'junit:junit:4.12'
17 | }
18 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": {
3 | "bundleName": "com.istone.myapplication",
4 | "vendor": "istone",
5 | "version": {
6 | "code": 1,
7 | "name": "1.0"
8 | },
9 | "apiVersion": {
10 | "compatible": 4,
11 | "target": 4,
12 | "releaseType": "Beta1"
13 | }
14 | },
15 | "deviceConfig": {},
16 | "module": {
17 | "package": "com.istone.glidelibrary",
18 | "deviceType": [
19 | "phone"
20 | ],
21 | "distro": {
22 | "deliveryWithInstall": true,
23 | "moduleName": "glidelibrary",
24 | "moduleType": "har"
25 | },
26 | "reqPermissions": [
27 | {
28 | "name": "ohos.permission.GET_NETWORK_INFO"
29 | },
30 | {
31 | "name": "ohos.permission.GET_WIFI_INFO"
32 | },
33 | {
34 | "name": "ohos.permission.INTERNET"
35 | },
36 | {
37 | "name": "ohos.permission.READ_MEDIA"
38 | },
39 | {
40 | "name": "ohos.permission.WRITE_MEDIA"
41 | },
42 | {
43 | "name": "ohos.permission.READ_USER_STORAGE"
44 | },
45 | {
46 | "name": "ohos.permission.WRITE_USER_STORAGE"
47 | }
48 | ]
49 | }
50 | }
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/FileType.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary;
2 |
3 | /**
4 | * description glide 网络文件类型
5 | *
6 | * @author baihe
7 | * created 2021/2/8 11:53
8 | */
9 | public enum FileType {
10 | /**
11 | * png gif
12 | */
13 | PNG, GIF
14 | }
15 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/cache/loader/CacheLoader.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.cache.loader;
2 |
3 | import com.bumptech.glide.util.LruCache;
4 | import ohos.media.image.PixelMap;
5 |
6 | /**
7 | * description CacheLoader
8 | *
9 | * @author baihe
10 | * created 2021/2/9 8:41
11 | */
12 | public class CacheLoader {
13 | /**
14 | * lruCache
15 | */
16 | private LruCache lruCache;
17 |
18 | /**
19 | * CacheLoader
20 | */
21 | public CacheLoader() {
22 | //设置最大缓存空间为运行时内存的 1/8
23 | int maxMemory = (int) Runtime.getRuntime().maxMemory();
24 | int cacheSize = maxMemory / 8;
25 | lruCache = new LruCache<>(cacheSize);
26 |
27 | }
28 |
29 | /**
30 | * 添加图片到 LruCache
31 | *
32 | * @param key key
33 | * @param pixelMap pixelMap
34 | */
35 | public void addBitmap(String key, PixelMap pixelMap) {
36 | if (getPixelMap(key) == null) {
37 | lruCache.put(key, pixelMap);
38 | }
39 | }
40 |
41 | /**
42 | * 从缓存中获取资源
43 | *
44 | * @param key key
45 | * @return PixelMap
46 | */
47 | public PixelMap getPixelMap(String key) {
48 | return lruCache.get(key);
49 | }
50 |
51 | /**
52 | * 从缓存中删除指定的PixelMap
53 | *
54 | * @param key key
55 | */
56 | public void removePixelMapFromMemory(String key) {
57 | lruCache.remove(key);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/cache/util/CacheUtils.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.cache.util;
2 |
3 | import java.security.MessageDigest;
4 | import java.security.NoSuchAlgorithmException;
5 |
6 | /**
7 | * description CacheUtils
8 | *
9 | * @author baihe
10 | * created 2021/2/9 8:41
11 | */
12 | public class CacheUtils {
13 |
14 | /**
15 | * 将用于缓存的key转成MD5字符串,以确保唯一性
16 | *
17 | * @param key key
18 | * @return String
19 | */
20 | public static String hashKeyForCache(String key) {
21 | if (key != null) {
22 | String cacheKey;
23 | try {
24 | final MessageDigest mDigest = MessageDigest.getInstance("MD5");
25 | mDigest.update(key.getBytes());
26 | cacheKey = bytesToHexString(mDigest.digest());
27 | } catch (NoSuchAlgorithmException e) {
28 | cacheKey = String.valueOf(key.hashCode());
29 | }
30 | return cacheKey;
31 | }
32 | return null;
33 | }
34 |
35 | /**
36 | * @param bytes bytes
37 | * @return String
38 | */
39 | private static String bytesToHexString(byte[] bytes) {
40 | StringBuilder sb = new StringBuilder();
41 | for (int i = 0; i < bytes.length; i++) {
42 | String hex = Integer.toHexString(0xFF & bytes[i]);
43 | if (hex.length() == 1) {
44 | sb.append('0');
45 | }
46 | sb.append(hex);
47 | }
48 | return sb.toString();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/cache/util/DiskLruCache.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.cache.util;
2 |
3 |
4 | import com.isotne.glidelibrary.utils.LogUtils;
5 |
6 | import java.io.Closeable;
7 | import java.io.File;
8 | import java.io.IOException;
9 | import java.io.EOFException;
10 | import java.io.FileInputStream;
11 | import java.io.BufferedWriter;
12 | import java.io.FileOutputStream;
13 | import java.io.OutputStreamWriter;
14 | import java.io.InputStream;
15 | import java.io.FileNotFoundException;
16 | import java.io.InputStreamReader;
17 | import java.io.OutputStream;
18 | import java.io.FilterOutputStream;
19 | import java.io.Writer;
20 | import java.nio.charset.Charset;
21 | import java.util.ArrayList;
22 | import java.util.Iterator;
23 | import java.util.LinkedHashMap;
24 | import java.util.Map;
25 | import java.util.concurrent.Callable;
26 | import java.util.concurrent.LinkedBlockingQueue;
27 | import java.util.concurrent.ThreadPoolExecutor;
28 | import java.util.concurrent.TimeUnit;
29 | import java.util.regex.Matcher;
30 | import java.util.regex.Pattern;
31 |
32 | /**
33 | * description DiskLruCache
34 | *
35 | * @author baihe
36 | * created 2021/2/9 8:41
37 | */
38 | public final class DiskLruCache implements Closeable {
39 | /**
40 | * JOURNAL_FILE
41 | */
42 | static final String JOURNAL_FILE = "journal";
43 | /**
44 | * JOURNAL_FILE_TEMP
45 | */
46 | static final String JOURNAL_FILE_TEMP = "journal.tmp";
47 | /**
48 | * JOURNAL_FILE_BACKUP
49 | */
50 | static final String JOURNAL_FILE_BACKUP = "journal.bkp";
51 | /**
52 | * MAGIC
53 | */
54 | static final String MAGIC = "libcore.io.DiskLruCache";
55 | /**
56 | * VERSION_1
57 | */
58 | static final String VERSION_1 = "1";
59 | /**
60 | * ANY_SEQUENCE_NUMBER
61 | */
62 | static final long ANY_SEQUENCE_NUMBER = -1;
63 | /**
64 | * ANY_SEQUENCE_NUMBER
65 | */
66 | static final String STRING_KEY_PATTERN = "[a-z0-9_-]{1,120}";
67 | /**
68 | * STRING_KEY_PATTERN
69 | */
70 | static final Pattern LEGAL_KEY_PATTERN = Pattern.compile(STRING_KEY_PATTERN);
71 | /**
72 | * CLEAN
73 | */
74 | private static final String CLEAN = "CLEAN";
75 | /**
76 | * DIRTY
77 | */
78 | private static final String DIRTY = "DIRTY";
79 | /**
80 | * REMOVE
81 | */
82 | private static final String REMOVE = "REMOVE";
83 | /**
84 | * READ
85 | */
86 | private static final String READ = "READ";
87 | /**
88 | * directory
89 | */
90 | private final File directory;
91 | /**
92 | * journalFile
93 | */
94 | private final File journalFile;
95 | /**
96 | * journalFileTmp
97 | */
98 | private final File journalFileTmp;
99 | /**
100 | * journalFileBackup
101 | */
102 | private final File journalFileBackup;
103 | /**
104 | * appVersion
105 | */
106 | private final int appVersion;
107 | /**
108 | * maxSize
109 | */
110 | private long maxSize;
111 | /**
112 | * valueCount
113 | */
114 | private final int valueCount;
115 | /**
116 | * valueCount
117 | */
118 | private long size = 0;
119 | /**
120 | * journalWriter
121 | */
122 | private Writer journalWriter;
123 | /**
124 | * lruEntries
125 | */
126 | private final LinkedHashMap lruEntries =
127 | new LinkedHashMap(0, 0.75f, true);
128 | /**
129 | * redundantOpCount
130 | */
131 | private int redundantOpCount; // redundantOpCount
132 |
133 | /**
134 | * To differentiate between old and current snapshots, each entry is given
135 | * a sequence number each time an edit is committed. A snapshot is stale if
136 | * its sequence number is not equal to its entry's sequence number.
137 | */
138 | private long nextSequenceNumber = 0;
139 |
140 | /**
141 | * This cache uses a single background thread to evict entries.
142 | */
143 | private final ThreadPoolExecutor executorService =
144 | new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue());
145 | /**
146 | * cleanupCallable
147 | */
148 | private final Callable cleanupCallable = new Callable() {
149 | public Void call() throws Exception {
150 | synchronized (DiskLruCache.this) {
151 | if (journalWriter == null) {
152 | return null; // Closed.
153 | }
154 | trimToSize();
155 | if (journalRebuildRequired()) {
156 | rebuildJournal();
157 | redundantOpCount = 0;
158 | }
159 | }
160 | return null;
161 | }
162 | };
163 |
164 | private DiskLruCache(File directory, int appVersion, int valueCount, long maxSize) {
165 | this.directory = directory;
166 | this.appVersion = appVersion;
167 | this.journalFile = new File(directory, JOURNAL_FILE);
168 | this.journalFileTmp = new File(directory, JOURNAL_FILE_TEMP);
169 | this.journalFileBackup = new File(directory, JOURNAL_FILE_BACKUP);
170 | this.valueCount = valueCount;
171 | this.maxSize = maxSize;
172 | }
173 |
174 | /**
175 | * @param directory file path
176 | * @param appVersion appversion
177 | * @param valueCount valueCount
178 | * @param maxSize maxSize
179 | * @return DiskLruCache
180 | * @throws IOException exception
181 | */
182 | public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
183 | throws IOException {
184 | if (maxSize <= 0) {
185 | throw new IllegalArgumentException("maxSize <= 0");
186 | }
187 | if (valueCount <= 0) {
188 | throw new IllegalArgumentException("valueCount <= 0");
189 | }
190 |
191 | // If a bkp file exists, use it instead.
192 | File backupFile = new File(directory, JOURNAL_FILE_BACKUP);
193 | if (backupFile.exists()) {
194 | File journalFile = new File(directory, JOURNAL_FILE);
195 | // If journal file also exists just delete backup file.
196 | if (journalFile.exists()) {
197 | backupFile.delete();
198 | } else {
199 | renameTo(backupFile, journalFile, false);
200 | }
201 | }
202 |
203 | // Prefer to pick up where we left off.
204 | DiskLruCache cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
205 | if (cache.journalFile.exists()) {
206 | try {
207 | cache.readJournal();
208 | cache.processJournal();
209 | return cache;
210 | } catch (IOException journalIsCorrupt) {
211 | System.out
212 | .println("DiskLruCache "
213 | + directory
214 | + " is corrupt: "
215 | + journalIsCorrupt.getMessage()
216 | + ", removing");
217 | cache.delete();
218 | }
219 | }
220 |
221 | // Create a new empty cache.
222 | directory.mkdirs();
223 | cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
224 | cache.rebuildJournal();
225 | return cache;
226 | }
227 |
228 | /**
229 | * @throws IOException exception
230 | */
231 | private void readJournal() throws IOException {
232 | InputStream inputStream = new FileInputStream(journalFile);
233 | StrictLineReader reader = new StrictLineReader(inputStream, Charset.forName("US-ASCII"));
234 | try {
235 | String magic = reader.readLine();
236 | String version = reader.readLine();
237 | String appVersionString = reader.readLine();
238 | String valueCountString = reader.readLine();
239 | String blank = reader.readLine();
240 | if (!MAGIC.equals(magic)
241 | || !VERSION_1.equals(version)
242 | || !Integer.toString(appVersion).equals(appVersionString)
243 | || !Integer.toString(valueCount).equals(valueCountString)
244 | || !"".equals(blank)) {
245 | throw new IOException("unexpected journal header: [" + magic + ", " + version + ", "
246 | + valueCountString + ", " + blank + "]");
247 |
248 | }
249 |
250 | int lineCount = 0;
251 | while (true) {
252 | try {
253 | readJournalLine(reader.readLine());
254 | lineCount++;
255 | } catch (EOFException endOfJournal) {
256 | break;
257 | }
258 | }
259 | redundantOpCount = lineCount - lruEntries.size();
260 |
261 | // If we ended on a truncated line, rebuild the journal before appending to it.
262 | if (reader.hasUnterminatedLine()) {
263 | rebuildJournal();
264 | } else {
265 | journalWriter = new BufferedWriter(new OutputStreamWriter(
266 | new FileOutputStream(journalFile, true), Charset.forName("US-ASCII")));
267 | }
268 | } finally {
269 | Utils.closeQuietly(reader);
270 | }
271 | }
272 |
273 | /**
274 | * @param line line
275 | * @throws IOException IOException
276 | */
277 | private void readJournalLine(String line) throws IOException {
278 | int firstSpace = line.indexOf(' ');
279 | if (firstSpace == -1) {
280 | throw new IOException("unexpected journal line: " + line);
281 | }
282 |
283 | int keyBegin = firstSpace + 1;
284 | int secondSpace = line.indexOf(' ', keyBegin);
285 | final String key;
286 | if (secondSpace == -1) {
287 | key = line.substring(keyBegin);
288 | if (firstSpace == REMOVE.length() && line.startsWith(REMOVE)) {
289 | lruEntries.remove(key);
290 | return;
291 | }
292 | } else {
293 | key = line.substring(keyBegin, secondSpace);
294 | }
295 |
296 | Entry entry = lruEntries.get(key);
297 | if (entry == null) {
298 | entry = new Entry(key);
299 | lruEntries.put(key, entry);
300 | }
301 |
302 | if (secondSpace != -1 && firstSpace == CLEAN.length() && line.startsWith(CLEAN)) {
303 | String[] parts = line.substring(secondSpace + 1).split(" ");
304 | entry.readable = true;
305 | entry.currentEditor = null;
306 | entry.setLengths(parts);
307 | } else if (secondSpace == -1 && firstSpace == DIRTY.length() && line.startsWith(DIRTY)) {
308 | entry.currentEditor = new Editor(entry);
309 | } else if (secondSpace == -1 && firstSpace == READ.length() && line.startsWith(READ)) {
310 | // This work was already done by calling lruEntries.get().
311 | } else {
312 | throw new IOException("unexpected journal line: " + line);
313 | }
314 | }
315 |
316 | /**
317 | * @throws IOException IOException
318 | */
319 | private void processJournal() throws IOException {
320 | deleteIfExists(journalFileTmp);
321 | for (Iterator i = lruEntries.values().iterator(); i.hasNext(); ) {
322 | Entry entry = i.next();
323 | if (entry.currentEditor == null) {
324 | for (int t = 0; t < valueCount; t++) {
325 | size += entry.lengths[t];
326 | }
327 | } else {
328 | entry.currentEditor = null;
329 | for (int t = 0; t < valueCount; t++) {
330 | deleteIfExists(entry.getCleanFile(t));
331 | deleteIfExists(entry.getDirtyFile(t));
332 | }
333 | i.remove();
334 | }
335 | }
336 | }
337 |
338 | /**
339 | * @throws IOException IOException
340 | */
341 | private synchronized void rebuildJournal() throws IOException {
342 | if (journalWriter != null) {
343 | journalWriter.close();
344 | }
345 |
346 | Writer writer = new BufferedWriter(
347 | new OutputStreamWriter(new FileOutputStream(journalFileTmp), Utils.US_ASCII));
348 | try {
349 | writer.write(MAGIC);
350 | writer.write("\n");
351 | writer.write(VERSION_1);
352 | writer.write("\n");
353 | writer.write(Integer.toString(appVersion));
354 | writer.write("\n");
355 | writer.write(Integer.toString(valueCount));
356 | writer.write("\n");
357 | writer.write("\n");
358 |
359 | for (Entry entry : lruEntries.values()) {
360 | if (entry.currentEditor != null) {
361 | writer.write(DIRTY + ' ' + entry.key + '\n');
362 | } else {
363 | writer.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n');
364 | }
365 | }
366 | } finally {
367 | writer.close();
368 | }
369 |
370 | if (journalFile.exists()) {
371 | renameTo(journalFile, journalFileBackup, true);
372 | }
373 | renameTo(journalFileTmp, journalFile, false);
374 | journalFileBackup.delete();
375 |
376 | journalWriter = new BufferedWriter(
377 | new OutputStreamWriter(new FileOutputStream(journalFile, true), Utils.US_ASCII));
378 | }
379 |
380 | /**
381 | * @param file file
382 | * @throws IOException IOException
383 | */
384 | private static void deleteIfExists(File file) throws IOException {
385 | if (file.exists() && !file.delete()) {
386 | throw new IOException();
387 | }
388 | }
389 |
390 | /**
391 | * @param from from
392 | * @param to to
393 | * @param deleteDestination deleteDestination
394 | * @throws IOException IOException
395 | */
396 | private static void renameTo(File from, File to, boolean deleteDestination) throws IOException {
397 | if (deleteDestination) {
398 | deleteIfExists(to);
399 | }
400 | if (!from.renameTo(to)) {
401 | throw new IOException();
402 | }
403 | }
404 |
405 | /**
406 | * @param key key
407 | * @return Snapshot
408 | * @throws IOException IOException
409 | */
410 | public synchronized Snapshot get(String key) throws IOException {
411 | checkNotClosed();
412 | validateKey(key);
413 | Entry entry = lruEntries.get(key);
414 | if (entry == null) {
415 | return null;
416 | }
417 |
418 | if (!entry.readable) {
419 | return null;
420 | }
421 |
422 | // Open all streams eagerly to guarantee that we see a single published
423 | // snapshot. If we opened streams lazily then the streams could come
424 | // from different edits.
425 | InputStream[] ins = new InputStream[valueCount];
426 | try {
427 | for (int i = 0; i < valueCount; i++) {
428 | ins[i] = new FileInputStream(entry.getCleanFile(i));
429 | }
430 | } catch (FileNotFoundException e) {
431 | LogUtils.log(LogUtils.ERROR, "AAA", "e=" + e.getMessage());
432 | // A file must have been deleted manually!
433 | for (int i = 0; i < valueCount; i++) {
434 | if (ins[i] != null) {
435 | Utils.closeQuietly(ins[i]);
436 | } else {
437 | break;
438 | }
439 | }
440 | return null;
441 | }
442 |
443 | redundantOpCount++;
444 | journalWriter.append(READ + ' ' + key + '\n');
445 | if (journalRebuildRequired()) {
446 | executorService.submit(cleanupCallable);
447 | }
448 |
449 | return new Snapshot(key, entry.sequenceNumber, ins, entry.lengths);
450 | }
451 |
452 | /**
453 | * @param key key
454 | * @return Editor
455 | * @throws IOException IOException
456 | */
457 | public Editor edit(String key) throws IOException {
458 | return edit(key, ANY_SEQUENCE_NUMBER);
459 | }
460 |
461 | /**
462 | * @param key key
463 | * @param expectedSequenceNumber expectedSequenceNumber
464 | * @return Editor
465 | * @throws IOException IOException
466 | */
467 | private synchronized Editor edit(String key, long expectedSequenceNumber) throws IOException {
468 | checkNotClosed();
469 | validateKey(key);
470 | Entry entry = lruEntries.get(key);
471 | if (expectedSequenceNumber != ANY_SEQUENCE_NUMBER && (entry == null
472 | || entry.sequenceNumber != expectedSequenceNumber)) {
473 | return null; // Snapshot is stale.
474 | }
475 | if (entry == null) {
476 | entry = new Entry(key);
477 | lruEntries.put(key, entry);
478 | } else if (entry.currentEditor != null) {
479 | return null; // Another edit is in progress.
480 | }
481 |
482 | Editor editor = new Editor(entry);
483 | entry.currentEditor = editor;
484 |
485 | // Flush the journal before creating files to prevent file leaks.
486 | journalWriter.write(DIRTY + ' ' + key + '\n');
487 | journalWriter.flush();
488 | return editor;
489 | }
490 |
491 | /**
492 | * @return File
493 | */
494 | public File getDirectory() {
495 | return directory;
496 | }
497 |
498 | /**
499 | * @return size
500 | */
501 | public synchronized long getMaxSize() {
502 | return maxSize;
503 | }
504 |
505 | /**
506 | * @param maxSize maxSize
507 | */
508 | public synchronized void setMaxSize(long maxSize) {
509 | this.maxSize = maxSize;
510 | executorService.submit(cleanupCallable);
511 | }
512 |
513 | /**
514 | * @return size
515 | */
516 | public synchronized long size() {
517 | return size;
518 | }
519 |
520 | /**
521 | * @param editor editor
522 | * @param success success
523 | * @throws IOException IOException
524 | */
525 | private synchronized void completeEdit(Editor editor, boolean success) throws IOException {
526 | Entry entry = editor.entry;
527 | if (entry.currentEditor != editor) {
528 | throw new IllegalStateException();
529 | }
530 |
531 | // If this edit is creating the entry for the first time, every index must have a value.
532 | if (success && !entry.readable) {
533 | for (int i = 0; i < valueCount; i++) {
534 | if (!editor.written[i]) {
535 | editor.abort();
536 | throw new IllegalStateException("Newly created entry didn't create value for index " + i);
537 | }
538 | if (!entry.getDirtyFile(i).exists()) {
539 | editor.abort();
540 | return;
541 | }
542 | }
543 | }
544 |
545 | for (int i = 0; i < valueCount; i++) {
546 | File dirty = entry.getDirtyFile(i);
547 | if (success) {
548 | if (dirty.exists()) {
549 | File clean = entry.getCleanFile(i);
550 | dirty.renameTo(clean);
551 | long oldLength = entry.lengths[i];
552 | long newLength = clean.length();
553 | entry.lengths[i] = newLength;
554 | size = size - oldLength + newLength;
555 | }
556 | } else {
557 | deleteIfExists(dirty);
558 | }
559 | }
560 |
561 | redundantOpCount++;
562 | entry.currentEditor = null;
563 | if (entry.readable | success) {
564 | entry.readable = true;
565 | journalWriter.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n');
566 | if (success) {
567 | entry.sequenceNumber = nextSequenceNumber++;
568 | }
569 | } else {
570 | lruEntries.remove(entry.key);
571 | journalWriter.write(REMOVE + ' ' + entry.key + '\n');
572 | }
573 | journalWriter.flush();
574 |
575 | if (size > maxSize || journalRebuildRequired()) {
576 | executorService.submit(cleanupCallable);
577 | }
578 | }
579 |
580 | /**
581 | *
582 | * @return boolean
583 | */
584 | private boolean journalRebuildRequired() {
585 | final int redundantOpCompactThreshold = 2000;
586 | return redundantOpCount >= redundantOpCompactThreshold //
587 | && redundantOpCount >= lruEntries.size();
588 | }
589 |
590 | /**
591 | * @param key key
592 | * @return true or false
593 | * @throws IOException IOException
594 | */
595 | public synchronized boolean remove(String key) throws IOException {
596 | checkNotClosed();
597 | validateKey(key);
598 | Entry entry = lruEntries.get(key);
599 | if (entry == null || entry.currentEditor != null) {
600 | return false;
601 | }
602 |
603 | for (int i = 0; i < valueCount; i++) {
604 | File file = entry.getCleanFile(i);
605 | if (file.exists() && !file.delete()) {
606 | throw new IOException("failed to delete " + file);
607 | }
608 | size -= entry.lengths[i];
609 | entry.lengths[i] = 0;
610 | }
611 |
612 | redundantOpCount++;
613 | journalWriter.append(REMOVE + ' ' + key + '\n');
614 | lruEntries.remove(key);
615 |
616 | if (journalRebuildRequired()) {
617 | executorService.submit(cleanupCallable);
618 | }
619 |
620 | return true;
621 | }
622 |
623 | /**
624 | * @return true or false
625 | */
626 | public synchronized boolean isClosed() {
627 | return journalWriter == null;
628 | }
629 |
630 | /**
631 | * checkNotClosed
632 | */
633 | private void checkNotClosed() {
634 | if (journalWriter == null) {
635 | throw new IllegalStateException("cache is closed");
636 | }
637 | }
638 |
639 | /**
640 | * @throws IOException IOException
641 | */
642 | public synchronized void flush() throws IOException {
643 | checkNotClosed();
644 | trimToSize();
645 | journalWriter.flush();
646 | }
647 |
648 | /**
649 | * @throws IOException IOException
650 | */
651 | public synchronized void close() throws IOException {
652 | if (journalWriter == null) {
653 | return; // Already closed.
654 | }
655 | for (Entry entry : new ArrayList(lruEntries.values())) {
656 | if (entry.currentEditor != null) {
657 | entry.currentEditor.abort();
658 | }
659 | }
660 | trimToSize();
661 | journalWriter.close();
662 | journalWriter = null;
663 | }
664 |
665 | /**
666 | * @throws IOException IOException
667 | */
668 | private void trimToSize() throws IOException {
669 | while (size > maxSize) {
670 | Map.Entry toEvict = lruEntries.entrySet().iterator().next();
671 | remove(toEvict.getKey());
672 | }
673 | }
674 |
675 | /**
676 | * @throws IOException IOException
677 | */
678 | public void delete() throws IOException {
679 | close();
680 | Utils.deleteContents(directory);
681 | }
682 |
683 | /**
684 | * @param key key
685 | */
686 | private void validateKey(String key) {
687 | Matcher matcher = LEGAL_KEY_PATTERN.matcher(key);
688 | if (!matcher.matches()) {
689 | throw new IllegalArgumentException("keys must match regex "
690 | + STRING_KEY_PATTERN + ": \"" + key + "\"");
691 | }
692 | }
693 |
694 | /**
695 | * @param in in
696 | * @return String
697 | * @throws IOException IOException
698 | */
699 | private static String inputStreamToString(InputStream in) throws IOException {
700 | return Utils.readFully(new InputStreamReader(in, Utils.UTF_8));
701 | }
702 |
703 | /**
704 | * description Snapshot
705 | *
706 | * @author baihe
707 | * created 2021/2/9 9:51
708 | */
709 | public final class Snapshot implements Closeable {
710 | /**
711 | * key
712 | */
713 | private final String key;
714 | /**
715 | * sequenceNumber
716 | */
717 | private final long sequenceNumber;
718 | /**
719 | * ins
720 | */
721 | private final InputStream[] ins;
722 | /**
723 | * lengths
724 | */
725 | private final long[] lengths;
726 |
727 | private Snapshot(String key, long sequenceNumber, InputStream[] ins, long[] lengths) {
728 | this.key = key;
729 | this.sequenceNumber = sequenceNumber;
730 | this.ins = ins;
731 | this.lengths = lengths;
732 | }
733 |
734 | /**
735 | * @return Editor
736 | * @throws IOException IOException
737 | */
738 | public Editor edit() throws IOException {
739 | return DiskLruCache.this.edit(key, sequenceNumber);
740 | }
741 |
742 | /**
743 | *
744 | * @param index index
745 | * @return InputStream
746 | */
747 | public InputStream getInputStream(int index) {
748 | return ins[index];
749 | }
750 |
751 | /**
752 | * @param index index
753 | * @return String
754 | * @throws IOException IOException
755 | */
756 | public String getString(int index) throws IOException {
757 | return inputStreamToString(getInputStream(index));
758 | }
759 |
760 | /**
761 | *
762 | * @param index index
763 | * @return length
764 | */
765 | public long getLength(int index) {
766 | return lengths[index];
767 | }
768 |
769 | /**
770 | * close
771 | */
772 | public void close() {
773 | for (InputStream in : ins) {
774 | Utils.closeQuietly(in);
775 | }
776 | }
777 | }
778 |
779 | /**
780 | * OutputStream
781 | */
782 | private static final OutputStream NULL_OUTPUT_STREAM = new OutputStream() {
783 | @Override
784 | public void write(int b) throws IOException {
785 | // Eat all writes silently. Nom nom.
786 | }
787 | };
788 |
789 | /**
790 | * Edits the values for an entry.
791 | */
792 | public final class Editor {
793 | /**
794 | * entry
795 | */
796 | private final Entry entry;
797 | /**
798 | * written
799 | */
800 | private final boolean[] written;
801 | /**
802 | * hasErrors
803 | */
804 | private boolean hasErrors;
805 | /**
806 | * committed
807 | */
808 | private boolean committed;
809 |
810 | private Editor(Entry entry) {
811 | this.entry = entry;
812 | this.written = (entry.readable) ? null : new boolean[valueCount];
813 | }
814 |
815 | /**
816 | * @param index index
817 | * @return InputStream
818 | * @throws IOException IOException
819 | */
820 | public InputStream newInputStream(int index) throws IOException {
821 | synchronized (DiskLruCache.this) {
822 | if (entry.currentEditor != this) {
823 | throw new IllegalStateException();
824 | }
825 | if (!entry.readable) {
826 | return null;
827 | }
828 | try {
829 | return new FileInputStream(entry.getCleanFile(index));
830 | } catch (FileNotFoundException e) {
831 | return null;
832 | }
833 | }
834 | }
835 |
836 | /**
837 | * @param index index
838 | * @return String
839 | * @throws IOException IOException
840 | */
841 | public String getString(int index) throws IOException {
842 | InputStream in = newInputStream(index);
843 | return in != null ? inputStreamToString(in) : null;
844 | }
845 |
846 | /**
847 | * @param index index
848 | * @return OutputStream
849 | * @throws IOException IOException
850 | */
851 | public OutputStream newOutputStream(int index) throws IOException {
852 | if (index < 0 || index >= valueCount) {
853 | throw new IllegalArgumentException("Expected index " + index + " to "
854 | + "be greater than 0 and less than the maximum value count "
855 | + "of " + valueCount);
856 | }
857 | synchronized (DiskLruCache.this) {
858 | if (entry.currentEditor != this) {
859 | throw new IllegalStateException();
860 | }
861 | if (!entry.readable) {
862 | written[index] = true;
863 | }
864 | File dirtyFile = entry.getDirtyFile(index);
865 | FileOutputStream outputStream;
866 | try {
867 | outputStream = new FileOutputStream(dirtyFile);
868 | } catch (FileNotFoundException e) {
869 | // Attempt to recreate the cache directory.
870 | directory.mkdirs();
871 | try {
872 | outputStream = new FileOutputStream(dirtyFile);
873 | } catch (FileNotFoundException e2) {
874 | // We are unable to recover. Silently eat the writes.
875 | return NULL_OUTPUT_STREAM;
876 | }
877 | }
878 | return new FaultHidingOutputStream(outputStream);
879 | }
880 | }
881 |
882 | /**
883 | * @param index index
884 | * @param value value
885 | * @throws IOException IOException
886 | */
887 | public void set(int index, String value) throws IOException {
888 | Writer writer = null;
889 | try {
890 | writer = new OutputStreamWriter(newOutputStream(index), Utils.UTF_8);
891 | writer.write(value);
892 | } finally {
893 | Utils.closeQuietly(writer);
894 | }
895 | }
896 |
897 | /**
898 | * @throws IOException IOException
899 | */
900 | public void commit() throws IOException {
901 | if (hasErrors) {
902 | completeEdit(this, false);
903 | remove(entry.key); // The previous entry is stale.
904 | } else {
905 | completeEdit(this, true);
906 | }
907 | committed = true;
908 | }
909 |
910 | /**
911 | * @throws IOException IOException
912 | */
913 | public void abort() throws IOException {
914 | completeEdit(this, false);
915 | }
916 |
917 | /**
918 | * abortUnlessCommitted
919 | */
920 | public void abortUnlessCommitted() {
921 | if (!committed) {
922 | try {
923 | abort();
924 | } catch (IOException ignored) {
925 | }
926 | }
927 | }
928 |
929 |
930 | private final class FaultHidingOutputStream extends FilterOutputStream {
931 | private FaultHidingOutputStream(OutputStream out) {
932 | super(out);
933 | }
934 |
935 | @Override
936 | public void write(int oneByte) {
937 | try {
938 | out.write(oneByte);
939 | } catch (IOException e) {
940 | hasErrors = true;
941 | }
942 | }
943 |
944 | @Override
945 | public void write(byte[] buffer, int offset, int length) {
946 | try {
947 | out.write(buffer, offset, length);
948 | } catch (IOException e) {
949 | hasErrors = true;
950 | }
951 | }
952 |
953 | @Override
954 | public void close() {
955 | try {
956 | out.close();
957 | } catch (IOException e) {
958 | hasErrors = true;
959 | }
960 | }
961 |
962 | @Override
963 | public void flush() {
964 | try {
965 | out.flush();
966 | } catch (IOException e) {
967 | hasErrors = true;
968 | }
969 | }
970 | }
971 | }
972 |
973 | private final class Entry {
974 | /**
975 | * key
976 | */
977 | private final String key;
978 |
979 | /**
980 | * Lengths of this entry's files.
981 | */
982 | private final long[] lengths;
983 |
984 | /**
985 | * True if this entry has ever been published.
986 | */
987 | private boolean readable;
988 |
989 | /**
990 | * The ongoing edit or null if this entry is not being edited.
991 | */
992 | private Editor currentEditor;
993 |
994 | /**
995 | * The sequence number of the most recently committed edit to this entry.
996 | */
997 | private long sequenceNumber;
998 |
999 | private Entry(String key) {
1000 | this.key = key;
1001 | this.lengths = new long[valueCount];
1002 | }
1003 |
1004 | /**
1005 | * @return String
1006 | * @throws IOException IOException
1007 | */
1008 | public String getLengths() throws IOException {
1009 | StringBuilder result = new StringBuilder();
1010 | for (long size : lengths) {
1011 | result.append(' ').append(size);
1012 | }
1013 | return result.toString();
1014 | }
1015 |
1016 | /**
1017 | * @param strings strings
1018 | * @throws IOException IOException
1019 | */
1020 | private void setLengths(String[] strings) throws IOException {
1021 | if (strings.length != valueCount) {
1022 | throw invalidLengths(strings);
1023 | }
1024 |
1025 | try {
1026 | for (int i = 0; i < strings.length; i++) {
1027 | lengths[i] = Long.parseLong(strings[i]);
1028 | }
1029 | } catch (NumberFormatException e) {
1030 | throw invalidLengths(strings);
1031 | }
1032 | }
1033 |
1034 | /**
1035 | * @param strings strings
1036 | * @return IOException
1037 | * @throws IOException IOException
1038 | */
1039 | private IOException invalidLengths(String[] strings) throws IOException {
1040 | throw new IOException("unexpected journal line: " + java.util.Arrays.toString(strings));
1041 | }
1042 |
1043 | /**
1044 | * @param i i
1045 | * @return File
1046 | */
1047 | public File getCleanFile(int i) {
1048 | return new File(directory, key + "." + i);
1049 | }
1050 |
1051 | /**
1052 | * @param i i
1053 | * @return File
1054 | */
1055 | public File getDirtyFile(int i) {
1056 | return new File(directory, key + "." + i + ".tmp");
1057 | }
1058 | }
1059 | }
1060 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/cache/util/DiskLruCacheImpl.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.cache.util;
2 |
3 | import com.isotne.glidelibrary.utils.LogUtils;
4 | import ohos.media.image.ImageSource;
5 | import ohos.media.image.PixelMap;
6 |
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 | import java.io.OutputStream;
10 | import java.io.File;
11 |
12 |
13 | /**
14 | * description DiskLruCacheImpl
15 | *
16 | * @author baihe
17 | * created 2021/2/9 8:39
18 | */
19 | public class DiskLruCacheImpl {
20 | /**
21 | * DISK_LRU_CACHE
22 | */
23 | private static DiskLruCache DISK_LRU_CACHE;
24 | /**
25 | * file
26 | */
27 | private File file;
28 |
29 | /**
30 | * @param path path
31 | * @throws IOException IOException
32 | */
33 | public DiskLruCacheImpl(String path) throws IOException {
34 | file = new File(path);
35 | if (DISK_LRU_CACHE == null) {
36 | DISK_LRU_CACHE = DiskLruCache.open(file, 1, 1, 1024 * 1024 * 10);
37 | }
38 |
39 | }
40 |
41 | /**
42 | * @param bytes bytes
43 | * @param key key
44 | */
45 | public void addDiskCache(byte[] bytes, String key) {
46 | if (DISK_LRU_CACHE == null) {
47 | return;
48 | }
49 | try {
50 | DiskLruCache.Editor editor = DISK_LRU_CACHE.edit(CacheUtils.hashKeyForCache(key));
51 | if (editor != null) {
52 |
53 | OutputStream outputStream = editor.newOutputStream(0);
54 | outputStream.write(bytes, 0, bytes.length);
55 | editor.commit();
56 | DISK_LRU_CACHE.flush();
57 | }
58 | } catch (IOException e) {
59 | e.printStackTrace();
60 | }
61 |
62 | }
63 |
64 | /**
65 | * @param key key
66 | * @return return
67 | */
68 | public PixelMap getDiskCache(String key) {
69 | DiskLruCache.Snapshot snapshot = null;
70 | try {
71 | snapshot = DISK_LRU_CACHE.get(CacheUtils.hashKeyForCache(key));
72 | if (snapshot != null) {
73 | InputStream inputStream = snapshot.getInputStream(0);
74 | if (inputStream != null) {
75 | ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
76 | sourceOptions.formatHint = "image/png";
77 | ImageSource imageSource = ImageSource.create(inputStream, sourceOptions);
78 | PixelMap pixelMap = imageSource.createPixelmap(null);
79 | return pixelMap;
80 | }
81 | }
82 | } catch (IOException e) {
83 | LogUtils.log(LogUtils.ERROR, "AAA", "e=" + e.getMessage());
84 | e.printStackTrace();
85 | }
86 |
87 | return null;
88 | }
89 |
90 | /**
91 | * @param key key
92 | * @return if removed
93 | * @throws IOException IOException
94 | */
95 | public boolean removeDiskCach(String key) throws IOException {
96 | boolean isTrue = false;
97 | if (!isSet(CacheUtils.hashKeyForCache(key))) {
98 | isTrue = DISK_LRU_CACHE.remove(CacheUtils.hashKeyForCache(key));
99 | }
100 | return isTrue;
101 | }
102 |
103 |
104 | /**
105 | * @param key key
106 | * @return isset
107 | * @throws IOException IOException
108 | */
109 | public boolean isSet(String key) throws IOException {
110 | if (getDiskCache(CacheUtils.hashKeyForCache(key)) != null) {
111 | return false;
112 | }
113 | return true;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/cache/util/DiskLruCacheUtil.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.cache.util;
2 |
3 | import com.isotne.glidelibrary.constant.Constents;
4 | import ohos.aafwk.ability.AbilitySlice;
5 | import okhttp3.Cache;
6 |
7 | import java.io.File;
8 |
9 | /**
10 | * description DiskLruCacheUtil
11 | *
12 | * @author baihe
13 | * created 2021/2/9 8:41
14 | */
15 | public class DiskLruCacheUtil {
16 | /**
17 | * getCache
18 | *
19 | * @return cache
20 | */
21 | public static Cache getCACHE() {
22 | return DiskLruCacheUtil.CACHE;
23 | }
24 |
25 | /**
26 | * setCache
27 | *
28 | * @param cache cache
29 | */
30 | public static void setCACHE(Cache cache) {
31 | DiskLruCacheUtil.CACHE = cache;
32 | }
33 |
34 | /**
35 | * cache
36 | */
37 | private static Cache CACHE;
38 |
39 | /**
40 | * @param abilitySlice abilitySlice
41 | */
42 | public DiskLruCacheUtil(AbilitySlice abilitySlice) {
43 | File file = new File(abilitySlice.getExternalCacheDir().toString(), Constents.DISK_CACHE_PATH);
44 | CACHE = new Cache(file, Constents.DISK_CACHE_SIZE);
45 | setCACHE(CACHE);
46 | }
47 |
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/cache/util/ImageUtils.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.cache.util;
2 |
3 | import ohos.aafwk.ability.AbilitySlice;
4 | import ohos.app.Environment;
5 | import ohos.media.image.ImagePacker;
6 | import ohos.media.image.PixelMap;
7 |
8 | import java.io.File;
9 | import java.io.FileNotFoundException;
10 | import java.io.FileOutputStream;
11 |
12 | /**
13 | * description ImageUtils
14 | *
15 | * @author baihe
16 | * created 2021/2/9 8:41
17 | */
18 | public class ImageUtils {
19 | /**
20 | * @param abilitySlice abilitySlice
21 | * @param pixelMap pixelMap
22 | * @param key key
23 | */
24 | public static void savePixelMapToImage(AbilitySlice abilitySlice, PixelMap pixelMap, String key) {
25 | ImagePacker imagePacker = ImagePacker.create();
26 | File file = new File(abilitySlice.getExternalFilesDir(Environment.DIRECTORY_PICTURES), key + ".jpeg");
27 | FileOutputStream outputStream = null;
28 | try {
29 | outputStream = new FileOutputStream(file);
30 | ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
31 | packingOptions.format = "image/jpeg";
32 | packingOptions.quality = 100;// 设置图片质量
33 | boolean result = imagePacker.initializePacking(outputStream, packingOptions);
34 | result = imagePacker.addImage(pixelMap);
35 | long dataSize = imagePacker.finalizePacking();
36 | } catch (FileNotFoundException e) {
37 | e.printStackTrace();
38 | }
39 |
40 |
41 | }
42 |
43 | /**
44 | *
45 | * @param abilitySlice abilitySlice
46 | * @param key key
47 | * @return File
48 | */
49 | public static File getFile(AbilitySlice abilitySlice, String key) {
50 | File file = new File(abilitySlice.getExternalFilesDir(Environment.DIRECTORY_PICTURES), key + ".jpeg");
51 | return file;
52 | }
53 |
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/cache/util/MemoryCacheUtil.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.cache.util;
2 |
3 | import com.isotne.glidelibrary.cache.loader.CacheLoader;
4 | import ohos.media.image.PixelMap;
5 |
6 | /**
7 | * description
8 | *
9 | * @author baihe
10 | * created 2021/2/8 11:52
11 | */
12 | public class MemoryCacheUtil {
13 | /**
14 | * CACHE_LOADER
15 | */
16 | private static CacheLoader CACHE_LOADER = new CacheLoader();
17 |
18 | /**
19 | * @param key key
20 | * @return if has key
21 | */
22 | public static boolean isCache(String key) {
23 | if (CACHE_LOADER.getPixelMap(CacheUtils.hashKeyForCache(key)) != null) {
24 | return true;
25 | }
26 | return false;
27 | }
28 |
29 | /**
30 | * @param key key
31 | * @param pixelMap pixelMap
32 | */
33 | public static void savePixelMap(String key, PixelMap pixelMap) {
34 | if (!isCache(key)) {
35 | CACHE_LOADER.addBitmap(CacheUtils.hashKeyForCache(key), pixelMap);
36 | }
37 | }
38 |
39 | /**
40 | * @param key key
41 | */
42 | public static void cleanCache(String key) {
43 | if (isCache(key)) {
44 | CACHE_LOADER.removePixelMapFromMemory(CacheUtils.hashKeyForCache(key));
45 | }
46 | }
47 |
48 | /**
49 | * @param key key
50 | * @return PixelMap
51 | */
52 | public static PixelMap getPixelMap(String key) {
53 | return CACHE_LOADER.getPixelMap(CacheUtils.hashKeyForCache(key));
54 |
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/cache/util/StrictLineReader.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.cache.util;
2 |
3 | import java.io.Closeable;
4 | import java.io.EOFException;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.io.ByteArrayOutputStream;
8 | import java.io.UnsupportedEncodingException;
9 | import java.nio.charset.Charset;
10 |
11 | /**
12 | * description StrictLineReader
13 | *
14 | * @author baihe
15 | * created 2021/2/9 8:50
16 | */
17 | public class StrictLineReader implements Closeable {
18 | /**
19 | * dr
20 | */
21 | private static final byte CR = (byte) '\r';
22 | /**
23 | * lf
24 | */
25 | private static final byte LF = (byte) '\n';
26 | /**
27 | * in
28 | */
29 | private final InputStream in;
30 | /**
31 | * charset
32 | */
33 | private final Charset charset;
34 |
35 | /**
36 | * buf
37 | */
38 | private byte[] buf;
39 | /**
40 | * pos
41 | */
42 | private int pos;
43 | /**
44 | * end
45 | */
46 | private int end;
47 |
48 | /**
49 | * Constructs a new {@code LineReader} with the specified charset and the default capacity.
50 | *
51 | * @param in the {@code InputStream} to read data from.
52 | * @param charset the charset used to decode data. Only US-ASCII, UTF-8 and ISO-8859-1 are
53 | * supported.
54 | * @throws NullPointerException if {@code in} or {@code charset} is null.
55 | * @throws IllegalArgumentException if the specified charset is not supported.
56 | */
57 | public StrictLineReader(InputStream in, Charset charset) {
58 | this(in, 8192, charset);
59 | }
60 |
61 | /**
62 | * Constructs a new {@code LineReader} with the specified capacity and charset.
63 | *
64 | * @param in the {@code InputStream} to read data from.
65 | * @param capacity the capacity of the buffer.
66 | * @param charset the charset used to decode data. Only US-ASCII, UTF-8 and ISO-8859-1 are
67 | * supported.
68 | * @throws NullPointerException if {@code in} or {@code charset} is null.
69 | * @throws IllegalArgumentException if {@code capacity} is negative or zero
70 | * or the specified charset is not supported.
71 | */
72 | private StrictLineReader(InputStream in, int capacity, Charset charset) {
73 | if (in == null || charset == null) {
74 | throw new NullPointerException();
75 | }
76 | if (capacity < 0) {
77 | throw new IllegalArgumentException("capacity <= 0");
78 | }
79 | if (!(charset.equals(Charset.forName("US-ASCII")))) {
80 | throw new IllegalArgumentException("Unsupported encoding");
81 | }
82 |
83 | this.in = in;
84 | this.charset = charset;
85 | buf = new byte[capacity];
86 | }
87 |
88 | /**
89 | * Closes the reader by closing the underlying {@code InputStream} and
90 | * marking this reader as closed.
91 | *
92 | * @throws IOException for errors when closing the underlying {@code InputStream}.
93 | */
94 | public void close() throws IOException {
95 | synchronized (in) {
96 | if (buf != null) {
97 | buf = null;
98 | in.close();
99 | }
100 | }
101 | }
102 |
103 | /**
104 | * Reads the next line. A line ends with {@code "\n"} or {@code "\r\n"},
105 | * this end of line marker is not included in the result.
106 | *
107 | * @return the next line from the input.
108 | * @throws IOException for underlying {@code InputStream} errors.
109 | * @throws EOFException for the end of source stream.
110 | */
111 | public String readLine() throws IOException {
112 | synchronized (in) {
113 | if (buf == null) {
114 | throw new IOException("LineReader is closed");
115 | }
116 |
117 | // Read more data if we are at the end of the buffered data.
118 | // Though it's an error to read after an exception, we will let {@code fillBuf()}
119 | // throw again if that happens; thus we need to handle end == -1 as well as end == pos.
120 | if (pos >= end) {
121 | fillBuf();
122 | }
123 | // Try to find LF in the buffered data and return the line if successful.
124 | for (int i = pos; i != end; ++i) {
125 | if (buf[i] == LF) {
126 | int lineEnd = (i != pos && buf[i - 1] == CR) ? i - 1 : i;
127 | String res = new String(buf, pos, lineEnd - pos, charset.name());
128 | pos = i + 1;
129 | return res;
130 | }
131 | }
132 |
133 | // Let's anticipate up to 80 characters on top of those already read.
134 | ByteArrayOutputStream out = new ByteArrayOutputStream(end - pos + 80) {
135 | @Override
136 | public String toString() {
137 | int length = (count > 0 && buf[count - 1] == CR) ? count - 1 : count;
138 | try {
139 | return new String(buf, 0, length, charset.name());
140 | } catch (UnsupportedEncodingException e) {
141 | throw new AssertionError(e); // Since we control the charset this will never happen.
142 | }
143 | }
144 | };
145 |
146 | while (true) {
147 | out.write(buf, pos, end - pos);
148 | // Mark unterminated line in case fillBuf throws EOFException or IOException.
149 | end = -1;
150 | fillBuf();
151 | // Try to find LF in the buffered data and return the line if successful.
152 | for (int i = pos; i != end; ++i) {
153 | if (buf[i] == LF) {
154 | if (i != pos) {
155 | out.write(buf, pos, i - pos);
156 | }
157 | pos = i + 1;
158 | return out.toString();
159 | }
160 | }
161 | }
162 | }
163 | }
164 |
165 | /**
166 | * @return boolean
167 | */
168 | public boolean hasUnterminatedLine() {
169 | return end == -1;
170 | }
171 |
172 | /**
173 | * @throws IOException IOException
174 | */
175 | private void fillBuf() throws IOException {
176 | int result = in.read(buf, 0, buf.length);
177 | if (result == -1) {
178 | throw new EOFException();
179 | }
180 | pos = 0;
181 | end = result;
182 | }
183 | }
184 |
185 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/cache/util/Utils.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.cache.util;
2 |
3 | import ohos.media.image.ImageSource;
4 | import ohos.media.image.PixelMap;
5 |
6 | import java.io.IOException;
7 | import java.io.Reader;
8 | import java.io.StringWriter;
9 | import java.io.InputStream;
10 | import java.io.File;
11 | import java.io.Closeable;
12 | import java.nio.charset.Charset;
13 |
14 | /**
15 | * description Utils
16 | *
17 | * @author baihe
18 | * created 2021/2/9 9:05
19 | */
20 | public final class Utils {
21 | /**
22 | * US_ASCII
23 | */
24 | public static final Charset US_ASCII = Charset.forName("US-ASCII");
25 | /**
26 | * 编码格式UTF_8
27 | */
28 | public static final Charset UTF_8 = Charset.forName("UTF-8");
29 |
30 | private Utils() {
31 | }
32 |
33 | /**
34 | * @param reader reader
35 | * @return String
36 | * @throws IOException IOException
37 | */
38 | public static String readFully(Reader reader) throws IOException {
39 | try {
40 | StringWriter writer = new StringWriter();
41 | char[] buffer = new char[1024];
42 | int count;
43 | while ((count = reader.read(buffer)) != -1) {
44 | writer.write(buffer, 0, count);
45 | }
46 | return writer.toString();
47 | } finally {
48 | reader.close();
49 | }
50 | }
51 |
52 | /**
53 | * @param dir file path
54 | * @throws IOException IOException
55 | */
56 | public static void deleteContents(File dir) throws IOException {
57 | File[] files = dir.listFiles();
58 | if (files == null) {
59 | throw new IOException("not a readable directory: " + dir);
60 | }
61 | for (File file : files) {
62 | if (file.isDirectory()) {
63 | deleteContents(file);
64 | }
65 | if (!file.delete()) {
66 | throw new IOException("failed to delete file: " + file);
67 | }
68 | }
69 | }
70 |
71 |
72 | /**
73 | * @param closeable closeable
74 | */
75 | public static void closeQuietly(/*Auto*/Closeable closeable) {
76 | if (closeable != null) {
77 | try {
78 | closeable.close();
79 | } catch (RuntimeException rethrown) {
80 | throw rethrown;
81 | } catch (Exception ignored) {
82 | }
83 | }
84 | }
85 |
86 | /**
87 | * @param inputStream InputStream
88 | * @return PixelMap
89 | */
90 | public static PixelMap getStringStream(InputStream inputStream) {
91 | try {
92 | ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
93 | srcOpts.formatHint = "image/png";
94 | ImageSource imageSource = ImageSource.create(inputStream, srcOpts);
95 | PixelMap pixelMap = imageSource.createPixelmap(new ImageSource.DecodingOptions());
96 | return pixelMap;
97 |
98 | } catch (Exception ex) {
99 | ex.printStackTrace();
100 |
101 | }
102 | return null;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/constant/Constents.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.constant;
2 |
3 | /**
4 | * description 常量
5 | *
6 | * @author baihe
7 | * created 2021/2/8 14:37
8 | */
9 | public class Constents {
10 | /**
11 | * 缓存目录
12 | */
13 | public static final String DISK_CACHE_PATH = "cache";
14 | /**
15 | * 缓存大小
16 | */
17 | public static final long DISK_CACHE_SIZE = 10 * 1024 * 1024;
18 | }
19 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/gif/LoadGif.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.gif;
2 |
3 | import ohos.aafwk.ability.AbilitySlice;
4 | import ohos.agp.animation.Animator;
5 | import ohos.agp.animation.AnimatorValue;
6 | import ohos.agp.components.Image;
7 | import ohos.media.image.PixelMap;
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | /**
13 | * description 展示动画
14 | *
15 | * @author baihe
16 | * created 2021/2/8 14:34
17 | */
18 | public class LoadGif {
19 | /**
20 | * pixelmap list
21 | */
22 | private static List PIXEL_MAP_LIST = new ArrayList<>();
23 | /**
24 | * image
25 | */
26 | private static Image IMAGE;
27 | /**
28 | * animatorvalue
29 | */
30 | private static AnimatorValue ANIMATOR_VALUE;
31 |
32 | /**
33 | * @param abilitySlice abilitySlice
34 | * @param pixelMapList pixelMapList
35 | * @param image image
36 | * @param i i
37 | */
38 | public static void loadGif(AbilitySlice abilitySlice, List pixelMapList, Image image, int i) {
39 | IMAGE = image;
40 | PIXEL_MAP_LIST = pixelMapList;
41 | ANIMATOR_VALUE = new AnimatorValue();
42 | ANIMATOR_VALUE.setCurveType(Animator.CurveType.LINEAR);
43 | ANIMATOR_VALUE.setDelay(100);
44 | ANIMATOR_VALUE.setLoopedCount(Animator.INFINITE);//无限次循环
45 | ANIMATOR_VALUE.setDuration(i / 3 * 100);
46 | ANIMATOR_VALUE.setValueUpdateListener(M_ANIMATOR_UPDATE_LISTENER);
47 | ANIMATOR_VALUE.start();
48 |
49 | }
50 |
51 | /**
52 | * M_ANIMATOR_UPDATE_LISTENER
53 | */
54 | private static final AnimatorValue.ValueUpdateListener M_ANIMATOR_UPDATE_LISTENER
55 | = new AnimatorValue.ValueUpdateListener() {
56 | @Override
57 | public void onUpdate(AnimatorValue animatorValue, float v) {
58 | IMAGE.setPixelMap(PIXEL_MAP_LIST.get((int) (v * PIXEL_MAP_LIST.size())));
59 | IMAGE.invalidate();
60 | }
61 | };
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/interceptor/NetCacheInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.interceptor;
2 |
3 | import okhttp3.Interceptor;
4 | import okhttp3.Request;
5 | import okhttp3.Response;
6 |
7 | import java.io.IOException;
8 |
9 | /**
10 | * description 网络拦截器
11 | *
12 | * @author baihe
13 | * created 2021/2/8 14:35
14 | */
15 | public class NetCacheInterceptor implements Interceptor {
16 | @Override
17 | public Response intercept(Chain chain) throws IOException {
18 | Request request = chain.request();
19 | Response originResponse = chain.proceed(request);
20 |
21 | //设置响应的缓存时间为60秒,即设置Cache-Control头,并移除pragma消息头,因为pragma也是控制缓存的一个消息头属性
22 | originResponse = originResponse.newBuilder()
23 | .removeHeader("pragma")
24 | .header("Cache-Control", "max-age=60")
25 | .build();
26 |
27 | return originResponse;
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/okhttp/OkHttpManager.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.okhttp;
2 |
3 | import com.isotne.glidelibrary.cache.util.DiskLruCacheUtil;
4 | import com.isotne.glidelibrary.interceptor.NetCacheInterceptor;
5 | import okhttp3.CacheControl;
6 | import okhttp3.Callback;
7 | import okhttp3.OkHttpClient;
8 | import okhttp3.Request;
9 |
10 | import java.util.concurrent.TimeUnit;
11 |
12 | /**
13 | * description OKhttp manager
14 | *
15 | * @author baihe
16 | * created 2021/2/8 14:35
17 | */
18 | public final class OkHttpManager {
19 | /**
20 | * client
21 | */
22 | private OkHttpClient client;
23 |
24 | private OkHttpManager() {
25 | client = new OkHttpClient.Builder()
26 | .cache(DiskLruCacheUtil.getCACHE()) // 配置缓存
27 | .addNetworkInterceptor(new NetCacheInterceptor())
28 | .build();
29 | }
30 |
31 | /**
32 | * getInstance
33 | *
34 | * @return OkHttpManager
35 | */
36 | public static OkHttpManager getInstance() {
37 | return OkHttpHolder.INSTANCE;
38 | }
39 |
40 | /**
41 | * OkHttpHolder
42 | */
43 | private static class OkHttpHolder {
44 | /**
45 | * OkHttpManager 单例
46 | */
47 | private static final OkHttpManager INSTANCE = new OkHttpManager();
48 | }
49 |
50 | /**
51 | * @param callback callback
52 | * @param url url
53 | */
54 | public void asyncGet(Callback callback, String url) {
55 | CacheControl cacheControl = new CacheControl.Builder()
56 | .maxStale(10000, TimeUnit.SECONDS)
57 | .maxAge(100000, TimeUnit.SECONDS)
58 | .build();
59 |
60 | Request request = new Request.Builder()
61 | .url(url)
62 | .cacheControl(cacheControl)
63 | .build();
64 |
65 | client.newCall(request).enqueue(callback);
66 | }
67 | }
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/utils/LogUtils.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.utils;
2 |
3 | import ohos.hiviewdfx.HiLog;
4 | import ohos.hiviewdfx.HiLogLabel;
5 |
6 | /**
7 | * description log util
8 | *
9 | * @author baihe
10 | * created 2021/2/8 14:35
11 | */
12 | public class LogUtils {
13 | /**
14 | * INFO
15 | */
16 | public static final int INFO = 0;
17 | /**
18 | *ERROR
19 | */
20 | public static final int ERROR = 1;
21 | /**
22 | *DEBUG
23 | */
24 | public static final int DEBUG = 2;
25 | /**
26 | *WARN
27 | */
28 | public static final int WARN = 3;
29 |
30 | /**
31 | * @param logType LogUtils.INFO || LogUtils.ERROR || LogUtils.DEBUG|| LogUtils.WARN
32 | * @param tag 日志标识 根据喜好,自定义
33 | * @param message 需要打印的日志信息
34 | */
35 | public static void log(int logType, String tag, String message) {
36 | HiLogLabel lable = new HiLogLabel(HiLog.LOG_APP, 0x0, tag);
37 | switch (logType) {
38 | case INFO:
39 | HiLog.info(lable, message);
40 | break;
41 | case ERROR:
42 | HiLog.error(lable, message);
43 | break;
44 | case DEBUG:
45 | HiLog.debug(lable, message);
46 | break;
47 | case WARN:
48 | HiLog.warn(lable, message);
49 | break;
50 | default:
51 | break;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/java/com/isotne/glidelibrary/utils/OhosGlide.java:
--------------------------------------------------------------------------------
1 | package com.isotne.glidelibrary.utils;
2 |
3 | import com.isotne.glidelibrary.FileType;
4 | import com.isotne.glidelibrary.cache.util.DiskLruCacheImpl;
5 | import com.isotne.glidelibrary.cache.util.MemoryCacheUtil;
6 | import com.isotne.glidelibrary.constant.Constents;
7 | import com.isotne.glidelibrary.gif.LoadGif;
8 | import com.isotne.glidelibrary.okhttp.OkHttpManager;
9 | import ohos.aafwk.ability.AbilitySlice;
10 | import ohos.agp.animation.AnimatorValue;
11 | import ohos.agp.components.Image;
12 | import ohos.media.image.ImageSource;
13 | import ohos.media.image.PixelMap;
14 | import okhttp3.Call;
15 | import okhttp3.Callback;
16 | import okhttp3.Response;
17 |
18 | import java.io.FileOutputStream;
19 | import java.io.IOException;
20 | import java.io.InputStream;
21 | import java.io.File;
22 | import java.util.ArrayList;
23 | import java.util.List;
24 |
25 | /**
26 | * description 鸿蒙 Glide 组件
27 | *
28 | * @author baihe
29 | * created 2021/2/8 11:54
30 | */
31 | public class OhosGlide {
32 | /**
33 | * abilitySlice
34 | */
35 | private AbilitySlice abilitySlice;
36 | /**
37 | * url 图片地址
38 | */
39 | private String url = null;
40 | /**
41 | * inputstream
42 | */
43 | private InputStream inputStream;
44 | /**
45 | * default imager resources id
46 | */
47 | private int defImage;
48 | /**
49 | * iamge
50 | */
51 | private Image image;
52 | /**
53 | * whole image
54 | */
55 | private PixelMap pixelMap;
56 | /**
57 | * file type
58 | */
59 | private FileType fileType;
60 | /**
61 | * diskLruCacheImpl
62 | */
63 | private DiskLruCacheImpl diskLruCacheImpl;
64 | /**
65 | * pixelmap list
66 | */
67 | private List pixelMapList = new ArrayList<>();
68 | /**
69 | * animatorvalue
70 | */
71 | private AnimatorValue animatorValue;
72 |
73 | /**
74 | * init disk
75 | *
76 | * @param ability
77 | * @throws IOException
78 | */
79 | public OhosGlide(AbilitySlice ability) throws IOException {
80 | this.abilitySlice = ability;
81 | if (diskLruCacheImpl == null) {
82 | diskLruCacheImpl =
83 | new DiskLruCacheImpl(abilitySlice.getExternalCacheDir().toString() + "/" + Constents.DISK_CACHE_PATH);
84 |
85 | }
86 |
87 | }
88 |
89 |
90 |
91 | /**
92 | * init glide
93 | *
94 | * @param ability ability
95 | * @return OhosGlide
96 | * @throws IOException IOException
97 | */
98 | public static OhosGlide with(AbilitySlice ability) throws IOException {
99 |
100 | return new OhosGlide(ability);
101 | }
102 |
103 | /**
104 | * load url
105 | *
106 | * @param url url
107 | * @return OhosGlide
108 | */
109 | public OhosGlide load(String url) {
110 | this.url = url;
111 | return this;
112 | }
113 |
114 | /**
115 | * load inputstream
116 | *
117 | * @param inputStream inputStream
118 | * @return OhosGlide
119 | */
120 | public OhosGlide load(InputStream inputStream) {
121 | this.inputStream = inputStream;
122 | return this;
123 | }
124 |
125 | /**
126 | * 设置默认图片,当发生异常时使用
127 | *
128 | * @param defImage defImage
129 | * @return OhosGlide
130 | */
131 | public OhosGlide def(int defImage) {
132 | this.defImage = defImage;
133 | return this;
134 | }
135 |
136 | /**
137 | * if set cache
138 | *
139 | * @param isDiskCache isDiskCache
140 | * @return OhosGlide
141 | */
142 | public OhosGlide hasDiskCache(boolean isDiskCache) {
143 | return this;
144 | }
145 |
146 | /**
147 | * 需要渲染的iamge
148 | *
149 | * @param image image
150 | */
151 | public void into(Image image) {
152 | this.image = image;
153 | if (url == null) {
154 | setLoalImage(inputStream);
155 | } else {
156 | if (url.contains(".png") || url.contains(".jpg") || url.contains(".jpeg") || url.contains(".bmp")) {
157 | fileType = FileType.PNG;
158 | } else if (url.contains(".gif")) {
159 | fileType = FileType.GIF;
160 | }
161 | boolean hasCache = MemoryCacheUtil.isCache(url);
162 | if (hasCache) {//内存有缓存
163 | abilitySlice.getUITaskDispatcher().asyncDispatch(() -> {
164 | PixelMap pixelMap = MemoryCacheUtil.getPixelMap(url);
165 | image.setPixelMap(pixelMap);
166 | });
167 |
168 | } else {
169 | pixelMap = diskLruCacheImpl.getDiskCache(url);
170 | if (pixelMap != null) {//磁盘有缓存
171 | abilitySlice.getUITaskDispatcher().asyncDispatch(() -> {
172 | image.setPixelMap(pixelMap);
173 | });
174 | } else {//从网络下载file
175 | downLoadFile();
176 | }
177 | }
178 | }
179 | }
180 |
181 | /**
182 | * downLoadFile
183 | */
184 | public void downLoadFile() {
185 | if (image == null) {
186 | image.setPixelMap(defImage);
187 | }
188 |
189 | OkHttpManager.getInstance().asyncGet(new Callback() {
190 | @Override
191 | public void onFailure(Call call, IOException e) {
192 |
193 | pixelMap = diskLruCacheImpl.getDiskCache(url);
194 | if (pixelMap != null) {
195 | abilitySlice.getUITaskDispatcher().asyncDispatch(() -> {
196 | image.setPixelMap(pixelMap);
197 | });
198 | } else {
199 | abilitySlice.getUITaskDispatcher().asyncDispatch(() -> {
200 | image.setPixelMap(defImage);
201 | });
202 | }
203 | }
204 |
205 | @Override
206 | public void onResponse(Call call, Response response) throws IOException {
207 |
208 | byte[] bytes = response.body().bytes();
209 | if (response.isSuccessful()) {
210 | if (fileType == FileType.PNG) {
211 | showImage(bytes);
212 | } else if (fileType == FileType.GIF) {
213 | showGif(response.body().byteStream());
214 | }
215 | diskLruCacheImpl.addDiskCache(bytes, url);
216 | }
217 | }
218 | }, url);
219 |
220 | }
221 |
222 | /**
223 | * 展示网络图片
224 | *
225 | * @param bytes bytes
226 | */
227 | private void showImage(byte[] bytes) {
228 | // File file = abilitySlice.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
229 | // convertToFile(file.getAbsolutePath(), inputStream);
230 | // File imgFile = new File(file.getAbsolutePath(), "test.png");
231 | ImageSource imageSource = ImageSource.create(bytes, new ImageSource.SourceOptions());
232 | pixelMap = imageSource.createPixelmap(new ImageSource.DecodingOptions());
233 |
234 | /**添加缩略图
235 | ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
236 | PixelMap thumbnailPixelmap = imageSource.createThumbnailPixelmap(decodingOpts, false);
237 | **/
238 |
239 | abilitySlice.getUITaskDispatcher().asyncDispatch(() -> {
240 |
241 | image.setPixelMap(pixelMap);
242 | MemoryCacheUtil.savePixelMap(url, pixelMap);
243 |
244 |
245 | });
246 | }
247 |
248 |
249 | /**
250 | * 展示gif
251 | */
252 | private int index = 0;
253 |
254 | /**
255 | *
256 | * @param inputStream inputStream
257 | */
258 | private void showGif(InputStream inputStream) {
259 |
260 | ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
261 | ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
262 | decodingOpts.allowPartialImage = true;
263 | sourceOptions.formatHint = "image/gif";
264 | ImageSource imageSource = ImageSource.create(inputStream, sourceOptions);
265 |
266 | if (imageSource != null) {
267 | index = 0;
268 | while (imageSource.createPixelmap(index, decodingOpts) != null) {
269 | pixelMapList.add(imageSource.createPixelmap(index, decodingOpts));
270 | index++;
271 | }
272 | }
273 | // start anim
274 | abilitySlice.getUITaskDispatcher().asyncDispatch(() -> {
275 | LoadGif.loadGif(abilitySlice, pixelMapList, image, index);
276 | });
277 | }
278 |
279 |
280 | /**
281 | * 展示本地图片
282 | *
283 | * @param inputStream inputStream
284 | */
285 | private void setLoalImage(InputStream inputStream) {
286 | ImageSource imageSource = ImageSource.create(inputStream, new ImageSource.SourceOptions());
287 | PixelMap pixelMap = imageSource.createPixelmap(new ImageSource.DecodingOptions());
288 | abilitySlice.getUITaskDispatcher().asyncDispatch(() -> {
289 | image.setPixelMap(pixelMap);
290 | });
291 | }
292 |
293 | /**
294 | * 将inputstream 转换为图片
295 | *
296 | * @param path path
297 | * @param inputStream inputStream
298 | */
299 | private void convertToFile(String path, InputStream inputStream) {
300 | File dir = new File(path);
301 | if (!dir.exists()) {
302 | dir.mkdirs();
303 | }
304 | File file = new File(dir, "test.png");
305 |
306 | try {
307 | FileOutputStream outputStream = new FileOutputStream(file);
308 | try {
309 | byte[] b = new byte[1024];
310 | int n;
311 | while ((n = inputStream.read(b)) != -1) {
312 | outputStream.write(b, 0, n);
313 | }
314 | inputStream.close();
315 | outputStream.close();
316 | } catch (IOException e) {
317 | e.printStackTrace();
318 | }
319 |
320 | } catch (Exception e) {
321 | e.printStackTrace();
322 | }
323 | }
324 |
325 |
326 |
327 |
328 |
329 | }
330 |
331 |
332 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/resources/base/element/string.json:
--------------------------------------------------------------------------------
1 | {
2 | "string": [
3 | {
4 | "name": "app_name",
5 | "value": "GlideLibrary"
6 | }
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/glidelibrary/src/main/resources/base/layout/ability_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. DevEco Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | # If the Chinese output is garbled, please configure the following parameter.
10 | # org.gradle.jvmargs=-Dfile.encoding=GBK
11 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isoftstone-dev/Gilde_HarmonyOS/ac12c5008fc5ccd2245fd303db3f7a0da39bb435/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 | # Determine the Java command to use to start the JVM.
86 | if [ -n "$JAVA_HOME" ] ; then
87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
88 | # IBM's JDK on AIX uses strange locations for the executables
89 | JAVACMD="$JAVA_HOME/jre/sh/java"
90 | else
91 | JAVACMD="$JAVA_HOME/bin/java"
92 | fi
93 | if [ ! -x "$JAVACMD" ] ; then
94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
95 |
96 | Please set the JAVA_HOME variable in your environment to match the
97 | location of your Java installation."
98 | fi
99 | else
100 | JAVACMD="java"
101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
102 |
103 | Please set the JAVA_HOME variable in your environment to match the
104 | location of your Java installation."
105 | fi
106 |
107 | # Increase the maximum file descriptors if we can.
108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
109 | MAX_FD_LIMIT=`ulimit -H -n`
110 | if [ $? -eq 0 ] ; then
111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
112 | MAX_FD="$MAX_FD_LIMIT"
113 | fi
114 | ulimit -n $MAX_FD
115 | if [ $? -ne 0 ] ; then
116 | warn "Could not set maximum file descriptor limit: $MAX_FD"
117 | fi
118 | else
119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
120 | fi
121 | fi
122 |
123 | # For Darwin, add options to specify how the application appears in the dock
124 | if $darwin; then
125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
126 | fi
127 |
128 | # For Cygwin or MSYS, switch paths to Windows format before running java
129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
132 | JAVACMD=`cygpath --unix "$JAVACMD"`
133 |
134 | # We build the pattern for arguments to be converted via cygpath
135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
136 | SEP=""
137 | for dir in $ROOTDIRSRAW ; do
138 | ROOTDIRS="$ROOTDIRS$SEP$dir"
139 | SEP="|"
140 | done
141 | OURCYGPATTERN="(^($ROOTDIRS))"
142 | # Add a user-defined pattern to the cygpath arguments
143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
145 | fi
146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
147 | i=0
148 | for arg in "$@" ; do
149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
151 |
152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
154 | else
155 | eval `echo args$i`="\"$arg\""
156 | fi
157 | i=`expr $i + 1`
158 | done
159 | case $i in
160 | 0) set -- ;;
161 | 1) set -- "$args0" ;;
162 | 2) set -- "$args0" "$args1" ;;
163 | 3) set -- "$args0" "$args1" "$args2" ;;
164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
170 | esac
171 | fi
172 |
173 | # Escape application args
174 | save () {
175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
176 | echo " "
177 | }
178 | APP_ARGS=`save "$@"`
179 |
180 | # Collect all arguments for the java command, following the shell quoting and substitution rules
181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
182 |
183 | exec "$JAVACMD" "$@"
184 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto init
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto init
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :init
68 | @rem Get command-line arguments, handling Windows variants
69 |
70 | if not "%OS%" == "Windows_NT" goto win9xME_args
71 |
72 | :win9xME_args
73 | @rem Slurp the command line arguments.
74 | set CMD_LINE_ARGS=
75 | set _SKIP=2
76 |
77 | :win9xME_args_slurp
78 | if "x%~1" == "x" goto execute
79 |
80 | set CMD_LINE_ARGS=%*
81 |
82 | :execute
83 | @rem Setup the command line
84 |
85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
86 |
87 | @rem Execute Gradle
88 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
89 |
90 | :end
91 | @rem End local scope for the variables with windows NT shell
92 | if "%ERRORLEVEL%"=="0" goto mainEnd
93 |
94 | :fail
95 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
96 | rem the _cmd.exe /c_ return code!
97 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
98 | exit /b 1
99 |
100 | :mainEnd
101 | if "%OS%"=="Windows_NT" endlocal
102 |
103 | :omega
104 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':entry', ':glidelibrary'
2 |
--------------------------------------------------------------------------------