Golang中使用gomobile gobind生成的.aar文件在后台运行约20分钟后被终止

Golang中使用gomobile gobind生成的.aar文件在后台运行约20分钟后被终止 你好,

我正在使用 gomobile 构建一个用于网络功能的 Android 库。然而,在手机屏幕关闭(应用仍在后台运行)大约 20 分钟后,我就无法再从 .aar 文件收到响应了。有没有办法让进程保持活动状态?我想到的一些方法是给 .aar 提供一个唤醒锁,或者将其用作绑定服务,但我不确定如何使用 gomobile 生成的 .aar 来实现这些。

非常感谢任何帮助。谢谢!

2 回复

这看起来像是你的程序逻辑被阻塞了,所以检查一下哪里有严重的阻塞。

更多关于Golang中使用gomobile gobind生成的.aar文件在后台运行约20分钟后被终止的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个典型的Android后台执行限制问题,与Golang本身关系不大。gomobile生成的.aar文件作为Android库运行时,会受系统后台服务限制影响。

你需要实现一个前台服务来保持进程活动。以下是示例代码:

Go端代码(main.go):

package main

import (
    "context"
    "log"
    "time"
)

//export StartForegroundService
func StartForegroundService() {
    go func() {
        ctx := context.Background()
        ticker := time.NewTicker(30 * time.Second)
        defer ticker.Stop()
        
        for {
            select {
            case <-ticker.C:
                // 保持网络连接或执行必要任务
                log.Println("Service still running")
            case <-ctx.Done():
                return
            }
        }
    }()
}

//export StopForegroundService
func StopForegroundService() {
    // 清理资源
}

func main() {}

Java端需要创建前台服务:

// ForegroundService.java
public class ForegroundService extends Service {
    private static final int NOTIFICATION_ID = 1;
    private static final String CHANNEL_ID = "gomobile_channel";
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        createNotificationChannel();
        Notification notification = buildNotification();
        startForeground(NOTIFICATION_ID, notification);
        
        // 调用Go代码
        GoLib.startForegroundService();
        
        return START_STICKY;
    }
    
    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                CHANNEL_ID,
                "GoMobile Service",
                NotificationManager.IMPORTANCE_LOW
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
    }
    
    private Notification buildNotification() {
        return new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("GoMobile Service")
            .setContentText("Running in background")
            .setSmallIcon(R.drawable.ic_notification)
            .build();
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

AndroidManifest.xml中添加:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

<service
    android:name=".ForegroundService"
    android:enabled="true"
    android:exported="false" />

启动服务:

// 在Activity或Application中
Intent serviceIntent = new Intent(context, ForegroundService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService(serviceIntent);
} else {
    context.startService(serviceIntent);
}

另外,如果你需要wakelock,可以在Go端通过JNI调用Android API:

//export AcquireWakeLock
func AcquireWakeLock() {
    // 通过JNI调用PowerManager.newWakeLock()
    // 需要实现对应的JNI桥接
}

注意:从Android 8.0(API 26)开始,后台服务限制更加严格,必须使用前台服务并显示通知才能长时间运行。同时要考虑电池优化和Doze模式的影响,可能需要申请忽略电池优化权限。

回到顶部