OpenHarmony与ArkUI-X的跨平台开发AtomGit Pocket
《AtomGit Pocket新手入门指南》 本文介绍了AtomGit Pocket跨平台应用的使用方法。该应用基于ArkUI-X框架开发,支持HarmonyOS、Android和iOS平台,主要用于搜索AtomGit平台的用户和项目。主要内容包括: 准备工作:获取AtomGit访问令牌和安装应用 使用指南:输入令牌后即可搜索用户或项目 技术架构:采用ArkUI-X框架,使用TypeScript/
AtomGit Pocket 新手入门教程
教程略有修改GitCode-AtomGit,但功能实现是一样的
本教程将指导完全没有编程经验的新手如何使用 AtomGit Pocket 应用。AtomGit Pocket 是一个基于 ArkUI-X 框架开发的跨平台移动应用,原生支持 HarmonyOS,可以在 Android 和 iOS 设备上运行,用于搜索 AtomGit 平台上的用户和项目。

目录
项目简介
AtomGit Pocket 是一款专为 AtomGit 平台设计的轻量级搜索工具,具有以下特点:
- 原生支持 HarmonyOS
- 跨平台支持:可在 Android 和 iOS 设备上运行
- 简洁易用:直观的用户界面,方便快速搜索
- 安全可靠:通过访问令牌进行身份验证
准备工作
在开始使用 AtomGit Pocket 之前,您需要完成以下准备工作:
获取 AtomGit 访问令牌
由于 AtomGit API 需要身份验证,您需要先获取个人访问令牌:
- 打开浏览器,访问 AtomGit 个人访问令牌页面
- 登录您的 AtomGit 账户
- 点击 “添加新令牌” 按钮
- 在 “名称” 字段中输入一个易于识别的名称,例如 “AtomGit Pocket”
- 选择合适的过期时间
- 在 “范围” 部分,确保选中 “api” 权限
- 点击 “创建个人访问令牌” 按钮
- 复制生成的令牌并妥善保存(注意:令牌只显示一次,请务必及时保存)
安装 AtomGit Pocket 应用
这一部分采用安卓模拟器
- 确保您的设备已开启允许安装未知来源应用的权限(对于 Android 设备)
- 下载最新版本的 AtomGit Pocket 应用安装包
- 在设备上找到下载的安装包并点击安装
- 安装完成后,在设备的应用列表中找到 AtomGit Pocket 图标并启动应用
应用使用指南
启动应用
首次启动 AtomGit Pocket 应用时,您会看到主界面,包含以下几个主要部分:
- 访问令牌输入框
- 搜索类型切换按钮(搜索用户 / 搜索项目)
- 搜索框
- 结果显示区域
输入访问令牌
- 在主界面上方找到 “访问令牌 (必需)” 输入框
- 将您在准备工作阶段获得的 AtomGit 访问令牌粘贴到此输入框中
- 注意:令牌是必需的,没有有效的令牌将无法进行搜索操作
搜索用户
-
确保 “搜索用户” 按钮处于激活状态(背景色为蓝色)
-
在搜索框中输入要查找的用户名或关键词
-
点击 “搜索” 按钮或按回车键开始搜索
-
等待搜索结果加载完成
-
在结果显示区域,您可以看到匹配的用户列表,每个用户项包含:
- 用户头像
- 用户名和登录名
- 用户主页链接
搜索项目
-
点击 “搜索项目” 按钮将其激活(背景色变为蓝色)
-
在搜索框中输入要查找的项目名或关键词
-
点击 “搜索” 按钮或按回车键开始搜索
-
等待搜索结果加载完成
-
在结果显示区域,您可以看到匹配的项目列表,每个项目项包含:
- 项目头像
- 项目名称和完整路径
- 项目描述
- 星标数和复刻数
- 项目主页链接
技术架构简述
AtomGit Pocket 使用了华为的 ArkUI-X 框架进行开发,主要技术栈包括:
- 编程语言:TypeScript/ETS(ArkTS)
- 框架:ArkUI-X
- 目标 SDK 版本:5.1.0
- 支持平台:HarmonyOS、Android、iOS
应用的主要组成部分包括:
-
UI 组件:
- Index 页面:主界面,负责用户交互
- UserItem 组件:用于展示用户信息
- ProjectItem 组件:用于展示项目信息
-
服务层:
- GitCodeApiService:负责与 GitCode API 进行通信,处理数据请求
-
能力模块:
- EntryAbility:应用的主入口点,管理应用生命周期
核心代码讲解
布局实现详解
AtomGit Pocket 的界面布局采用了 ArkUI-X 的声明式 UI 编程范式,主要使用了以下组件:
-
Column 和 Row 布局组件:
- Column:垂直布局容器,用于将子组件垂直排列
- Row:水平布局容器,用于将子组件水平排列
- space 属性:设置子组件之间的间距
-
常用 UI 组件:
- Text:文本显示组件
- TextInput:文本输入组件
- Button:按钮组件
- Image:图片显示组件
- Scroll:滚动容器组件
- ForEach:循环渲染组件
-
布局属性:
- width/height:设置组件的宽度和高度
- padding/margin:设置内边距和外边距
- backgroundColor:设置背景颜色
- borderRadius:设置圆角
- shadow:设置阴影效果
Index 页面的整体布局结构如下:
- 最外层使用 Column 组件垂直排列所有内容
- 顶部标题使用 Text 组件显示
- 访问令牌输入区域使用 Column 和 Row 组合布局
- 搜索类型切换按钮使用 Row 水平排列两个 Button
- 搜索框区域使用 Row 组合 TextInput 和 Button
- 结果显示区域使用 Scroll 包含 Column,支持滚动查看
布局实现代码示例
以下是 Index.ets 文件中的核心布局代码示例:
build() {
Column({ space: 16 }) { // 垂直布局容器,子组件间距16
// 标题
Text('AtomGit 搜索工具')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 20 })
// 访问令牌输入框
Column({ space: 8 }) {
Row() {
Text('访问令牌 (必需)')
.fontSize(14)
.fontColor('#FF4D4F').width('80%').textAlign(TextAlign.Start) Text('AtomGit API 需要访问令牌') .fontSize(12) .fontColor('#999999')
.width('20%')
.textAlign(TextAlign.End)
}
.width('100%')
TextInput({
placeholder: '请输入 AtomGit 访问令牌,获取地址: https://atomgit.com/-/profile/personal_access_tokens'
})
.placeholderColor('#999999').type(InputType.Password).width('100%') .height(48) .borderRadius(8) .border({ width: 1, color: '#E0E0E0' })
.padding({ left: 12, right: 12 })
}
.width('90%')
// 搜索类型切换按钮
Row({ space: 12 }) {
Button('搜索用户')
.width('45%')
.height(48)
.backgroundColor(this.searchType === 'users' ? '#007DFF' : '#F0F0F0')
.fontColor(this.searchType === 'users' ? '#FFFFFF' : '#333333')
.borderRadius(8)
.onClick(() => {
this.searchType = 'users';
})
Button('搜索项目')
.width('45%')
.height(48)
.backgroundColor(this.searchType === 'projects' ? '#007DFF' : '#F0F0F0')
.fontColor(this.searchType === 'projects' ? '#FFFFFF' : '#333333')
.borderRadius(8)
.onClick(() => {
this.searchType = 'projects';
})
}
.width('90%')
// 搜索框
Row({ space: 12 }) {
TextInput({
placeholder: `请输入要搜索的${this.searchType === 'users' ? '用户名' : '项目名'}`
})
.placeholderColor('#999999').width('75%').height(48).borderRadius(8) .border({ width: 1, color: '#E0E0E0' })
.padding({ left: 12, right: 12 })
Button('搜索')
.width('20%')
.height(48)
.backgroundColor('#007DFF').fontColor('#FFFFFF')
.borderRadius(8)
}
.width('90%')
// 结果显示区域
Scroll() {
Column({ space: 16 }) {
if (this.searchType === 'users' && this.users.length > 0) {
// 用户列表
ForEach(this.users, (user: AtomGitUser) => {
UserItem({ user: user })
}, (user: AtomGitUser) => user.id.toString())
} else if (this.searchType === 'projects' && this.projects.length > 0) {
// 项目列表
ForEach(this.projects, (project: AtomGitProject) => {
ProjectItem({ project: project })
}, (project: AtomGitProject) => project.id.toString())
}
}
.padding({ top: 16, bottom: 20 })
.width('90%')
}
.width('100%')
.height('50%')
}
.width('100%')
.height('100%')
.padding({ left: 16, right: 16 })
.backgroundColor('#F5F5F5')
}
UserItem 和 ProjectItem 组件的布局代码示例:
// UserItem.ets
build() {
Row({ space: 12 }) { // 水平布局容器
// 用户头像
Image(this.user.avatar_url || '默认头像URL')
.width(64)
.height(64)
.borderRadius(32) // 圆形头像
.objectFit(ImageFit.Cover)
// 用户信息
Column({ space: 4 }) { // 垂直布局容器
Text(this.user.name || this.user.login)
.fontSize(18)
.fontWeight(FontWeight.Medium)
.fontColor('#333333')
.width('100%')
.textAlign(TextAlign.Start)
Text(this.user.login)
.fontSize(14)
.fontColor('#666666')
.width('100%')
.textAlign(TextAlign.Start)
}
.flexGrow(1)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.padding(12)
.backgroundColor('#FFFFFF')
.borderRadius(8)
.shadow({ radius: 4, color: '#00000010', offsetX: 0, offsetY: 2 })
}
// ProjectItem.ets
build() {
Column({ space: 8 }) { // 垂直布局容器
// 项目基本信息
Row({ space: 12 }) { // 水平布局容器
// 项目头像
Image(this.project.avatar_url || '默认头像URL')
.width(48)
.height(48)
.borderRadius(8)
.objectFit(ImageFit.Cover)
// 项目名称和路径
Column({ space: 4 }) { // 垂直布局容器
Text(this.project.name)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.fontColor('#333333')
.width('100%')
.textAlign(TextAlign.Start)
Text(this.project.full_name)
.fontSize(12)
.fontColor('#666666')
.width('100%')
.textAlign(TextAlign.Start)
}
.flexGrow(1)
.alignItems(HorizontalAlign.Start)
}
// 项目描述
if (this.project.description) {
Text(this.project.description)
.fontSize(14)
.fontColor('#666666')
.width('100%')
.textAlign(TextAlign.Start)
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
// 项目统计信息
Row({ space: 24 }) { // 水平布局容器
Row({ space: 4 }) {
Text('⭐')
.fontSize(16)
Text(this.project.stargazers_count.toString())
.fontSize(14)
.fontColor('#666666')
}
Row({ space: 4 }) {
Text('')
.fontSize(16)
Text(this.project.forks_count.toString())
.fontSize(14)
.fontColor('#666666')
}
}
}
.width('100%')
.padding(16)
.backgroundColor('#FFFFFF')
.borderRadius(8)
.shadow({ radius: 4, color: '#00000010', offsetX: 0, offsetY: 2 })
}
API 调用详解
GitCodeApiService 类封装了与 AtomGit API 的所有交互,主要包括以下几个核心方法:
-
request 方法:
- 私有方法,作为所有 API 请求的基础方法
- 使用
@ohos.net.http模块发起 HTTP GET 请求 - 自动添加访问令牌到请求参数
- 处理各种 HTTP 响应状态码
- 包含完善的错误处理机制
-
searchUsers 方法:
- 公开方法,用于搜索用户
- 调用
/api/v5/search/users接口 - 设置查询参数
q(搜索关键词)和per_page(每页数量) - 返回 Promise<GitCodeUser[]> 类型的结果
-
searchProjects 方法:
- 公开方法,用于搜索项目
- 调用
/api/v5/search/repositories接口 - 设置查询参数
q(搜索关键词)和per_page(每页数量) - 返回 Promise<GitCodeProject[]> 类型的结果
API 调用流程:
- 用户在界面输入搜索关键词并点击搜索按钮
- Index 页面的 performSearch 方法被调用
- 根据搜索类型调用 GitCodeApiService 的相应方法
- GitCodeApiService 构造请求参数并调用 request 方法
- request 方法发送 HTTP 请求到 AtomGit API
- 接收到响应后进行解析和错误处理
- 将结果返回给 Index 页面更新界面显示
API 调用代码示例
以下是 AtomGitApiService.ets 文件中的核心 API 调用代码示例:
// AtomGitApiService 类定义
export class AtomGitApiService {
private baseUrl: string = 'https://atomgit.com';
private token: string = '';
// 设置访问令牌
setToken(token: string): void {
this.token = token;
}
// 核心请求方法
private async request<T>(endpoint: string, params: Map<string, string>): Promise<T> {
try {
// 构建完整 URL
let url = `${this.baseUrl}${endpoint}`;
// 添加访问令牌
if (this.token) {
params.set('access_token', encodeURIComponent(this.token));
}
// 拼接查询参数
const queryString = Array.from(params.entries())
.map((entry) => `${entry[0]}=${entry[1]})
.join('&');
const fullUrl = `${url}?${queryString}`;
// 发起 HTTP GET 请求
const httpRequest = http.createHttp();
const response = await httpRequest.request(fullUrl, {
method: http.RequestMethod.GET,
header: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'User-Agent': 'AtomGit-Pocket/1.0.0'
}
});
// 处理响应
if (response.responseCode === 200) {
const result = response.result as string;
return JSON.parse(result) as T;
} else if (response.responseCode === 401 || response.responseCode === 403) {
throw new Error(`认证失败: 请检查访问令牌是否有效或权限是否正确`);
} else if (response.responseCode === 404) {
throw new Error(`请求资源不存在: ${endpoint}`);
} else if (response.responseCode >= 500) {
throw new Error(`服务器错误: 请稍后重试`);
} else {
throw new Error(`请求失败: 错误码 ${response.responseCode}`);
}
} catch (error) {
// 错误处理
console.error('API Request error:', error);
const businessError = error as BusinessError;
let errorMsg = '网络请求失败';
if (businessError.code) {
switch (businessError.code) {
case 201: // 网络不可用
errorMsg = '网络不可用,请检查网络连接';
break;
case 202: // 服务器无响应
errorMsg = '服务器无响应,请稍后重试';
break;
case 203: // DNS 解析失败
errorMsg = 'DNS 解析失败,请检查网络配置';
break;
default:
errorMsg = `网络错误: ${businessError.message}`;
}
} else {
errorMsg = (error as Error).message;
}
throw new Error(errorMsg);
}
}
// 搜索用户方法
async searchUsers(query: string): Promise<AtomGitUser[]> {
if (!query) {
return [];
}
// 构建查询参数
const params = new Map<string, string>();
params.set('q', encodeURIComponent(query));
params.set('per_page', '20');
return this.request<AtomGitUser[]>('/api/v5/search/users', params);
}
// 搜索项目方法
async searchProjects(query: string): Promise<AtomGitProject[]> {
if (!query) {
return [];
}
// 构建查询参数
const params = new Map<string, string>();
params.set('q', encodeURIComponent(query));
params.set('per_page', '20');
return this.request<AtomGitProject[]>('/api/v5/search/repositories', params);
}
}
Index 页面中调用 API 的代码示例:
``typescript
// Index.ets 中的 performSearch 方法
async performSearch() {
if (!this.searchQuery) {
this.error = '请输入搜索关键词';
return;
}
if (!this.token) {
this.error = '请输入访问令牌,AtomGit API 需要认证';
return;
}
this.loading = true;
this.error = '';
try {
// 根据搜索类型调用相应的 API 方法
if (this.searchType === 'users') {
// 调用搜索用户 API
this.users = await this.atomGitApiService.searchUsers(this.searchQuery);
this.projects = [];
} else {
// 调用搜索项目 API
this.projects = await this.atomGitApiService.searchProjects(this.searchQuery);
this.users = [];
}
} catch (error) {
// 处理搜索错误
this.error = `搜索失败: ${(error as Error).message}`;
console.error('Search error:', error);
} finally {
this.loading = false;
}
}
故障排除
如果您在使用过程中遇到问题,请参考以下解决方案:
-
无法搜索到任何结果:
- 检查访问令牌是否正确输入且未过期
- 确认网络连接正常
- 尝试使用不同的关键词进行搜索
-
搜索结果为空:
- 检查搜索关键词是否准确
- 确认目标用户或项目确实存在于 AtomGit 平台上
-
应用闪退或卡死:
- 重启应用
- 检查设备存储空间是否充足
- 更新到最新版本的应用
-
网络请求失败:
- 检查设备网络连接是否正常
- 确认防火墙或代理设置是否阻止了应用的网络访问
- 尝试切换网络环境(如从 WiFi 切换到移动数据)
-
访问令牌认证失败:
- 确认访问令牌已正确复制粘贴
- 检查令牌是否已过期,如过期需重新生成
- 确认令牌具有 “api” 权限
动图演示

常见问题解答
Q: 为什么必须输入访问令牌?
A: AtomGit API 要求所有请求都必须经过身份验证以保护用户数据安全,因此需要提供有效的个人访问令牌。
Q: 访问令牌是否会过期?
A: 是的,当您创建访问令牌时可以选择过期时间,过期后需要重新生成新的令牌。
Q: 应用支持哪些平台?
A: AtomGit Pocket 原生支持 Harmony,跨平台支持 Android 和 iOS 平台。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)