Files
go-mobile-uiautomator/libs/session.go
2026-03-10 15:49:36 +08:00

87 lines
2.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package libs
import (
"encoding/json"
"fmt"
)
// Session 在 Device 基础上增加应用会话监控
// 每次 JSON-RPC 调用前检查目标应用是否仍在运行
// 如果应用退出或崩溃,会返回 SessionBrokenError
//
// 对应 Python 版本的 Session 类
type Session struct {
*Device
packageName string // 监控的应用包名
pid int // 应用启动时的 PID
}
// NewSession 创建一个新的应用会话
// 启动应用并记录其 PID
func NewSession(device *Device, packageName string, attach bool) (*Session, error) {
// 如果不是 attach 模式,先停止再启动应用
if !attach {
device.AppStop(packageName)
}
device.AppStart(packageName, "", false)
// 等待应用启动并获取 PID
pid, err := device.AppWait(packageName, 20.0, false)
if err != nil {
return nil, err
}
if pid == 0 {
return nil, &DeviceError{Message: fmt.Sprintf("应用 %s 启动失败", packageName)}
}
return &Session{
Device: device,
packageName: packageName,
pid: pid,
}, nil
}
// PackageName 返回会话监控的应用包名
func (s *Session) PackageName() string {
return s.packageName
}
// PID 返回应用的进程 ID
func (s *Session) PID() int {
return s.pid
}
// Running 检查应用是否仍在运行
func (s *Session) Running() bool {
currentPid := s.pidOfApp(s.packageName)
return currentPid == s.pid && s.pid > 0
}
// jsonrpcCall 重写 Device 的 jsonrpcCall增加会话状态检查
func (s *Session) jsonrpcCall(method string, params interface{}, timeout float64) (json.RawMessage, error) {
if !s.Running() {
return nil, &SessionBrokenError{
Message: fmt.Sprintf("应用 %s (PID: %d) 已退出", s.packageName, s.pid),
}
}
return s.Device.jsonrpcCall(method, params, timeout)
}
// Restart 重启应用
func (s *Session) Restart() error {
s.Device.AppStop(s.packageName)
s.Device.AppStart(s.packageName, "", false)
pid, err := s.Device.AppWait(s.packageName, 20.0, false)
if err != nil {
return err
}
s.pid = pid
return nil
}
// Close 关闭会话(停止应用)
func (s *Session) Close() {
s.Device.AppStop(s.packageName)
s.pid = 0
}