You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android如何绑定Service并在MainActivity的onResume前从Service获取数据

解决方案
  • 首先调整bindService的调用位置:将绑定逻辑从onCreate迁移到onStart方法中,同时在onStop中添加对应解绑逻辑,符合Android生命周期配对规范,避免内存泄漏。
  • 适配异步绑定特性:bindService本身是异步调用,onServiceConnected回调不会在onResume执行前同步触发,无法保证onResume执行时Service已经绑定完成,因此需要将依赖Service数据的逻辑抽为独立方法,分别在绑定成功回调、onResume中按需触发。
  • Service侧逻辑优化:当前ConenctTimezoneDb方法运行在主线程,后续实际发起网络请求时需要开启子线程执行,避免触发ANR,可通过自定义回调接口将请求结果回传给Activity。

修改后的核心代码示例

MainActivity 调整

public class MainActivity extends AppCompatActivity{
    ArrayList<City> selected_cities;
    ArrayList<City> cities;
    RecyclerView Rview;
    CitySelectedListAdapter adapter;
    final int REQUEST_CODE = 1;
    ICityDao dao;

    TimezoneService timezoneService ;
    boolean bound = false;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            timezoneService = ((TimezoneService.LocalBinder ) service).getService();
            Log.d("Service connected","Service Connected ");
            bound = true;
            // 绑定成功立刻加载数据更新UI
            loadDataAndUpdateUI();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            bound = false;
        }
    } ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dao = new CItyDao(this);
        selected_cities = new ArrayList<City>();
        showMessage("Created");
        create_City_list();
        Log.d("created","activity created ");
    }

    @Override
    protected void onStart() {
        super.onStart();
        // 可见时绑定服务
        Intent intent  = new Intent(this,TimezoneService.class);
        bindService(intent,connection,Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // 不可见时解绑服务,避免泄漏
        if (bound) {
            unbindService(connection);
            bound = false;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        showMessage("Resumed");
        Log.d("Resume","resume ");
        // 若已经绑定完成,直接加载数据
        if (bound) {
            loadDataAndUpdateUI();
        }
    }

    // 抽离依赖Service数据的UI逻辑为独立方法
    private void loadDataAndUpdateUI() {
        if (!bound || timezoneService == null) return;
        // 可在此调用Service的方法获取时区数据
        // timezoneService.ConenctTimezoneDb(自定义回调接收数据)
        selected_cities = cities.get(0).load(dao);
        if(selected_cities.size()!=0) {
            CreateListView();
        }
        for (int i =0;i< selected_cities.size();i++) {
            load_checkbox(selected_cities.get(i).getName());
        }
    }
}

TimezoneService 调整(网络请求加回调示例)

public class TimezoneService extends Service {
    private final IBinder binder = new LocalBinder();
    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_NOT_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d("Onbind","onBind ");
        return binder;
    }

    public class LocalBinder extends Binder {
        public TimezoneService getService() {
            return TimezoneService.this;
        }
    }

    // 自定义回调接口回传数据
    public interface OnTimezoneDataLoadListener {
        void onLoadSuccess(String data);
        void onLoadFailed(Exception e);
    }

    public void ConenctTimezoneDb(OnTimezoneDataLoadListener listener) {
        Log.d("connect timezone","connected with time zone db");
        // 网络请求开子线程执行
        new Thread(() -> {
            try {
                URL url = new URL("http://api.timezonedb.com/v2.1/list-time-zone?&format=xml&country=US");
                // 此处补充网络请求逻辑,拿到返回数据
                String result = 你的网络请求方法(url);
                // 切回主线程回调结果
                new Handler(Looper.getMainLooper()).post(() -> listener.onLoadSuccess(result));
            } catch (Exception e) {
                e.printStackTrace();
                new Handler(Looper.getMainLooper()).post(() -> listener.onLoadFailed(e));
            }
        }).start();
    }
}

内容的提问来源于stack exchange,提问作者Hizafa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 21:15:07