简体   繁体   English

Android:在后台(服务)实现同步服务(通过http发布)的最佳方法是什么

[英]Android: What is the best way to implement a synchronization service (via http post) in background (service)

Here is my last implementation of a basic Service used to sync data between a web service (with some HTTP POST request). 这是我在网络服务(带有一些HTTP POST请求)之间同步数据的基本服务的最新实现。

Basically, during application execution, I want to continue sending post (every 1 minute) to my web service. 基本上,在应用程序执行期间,我想继续将帖子(每1分钟)发送到我的Web服务。

package com.example.testservice;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

public class HelloService extends Service {
    private Looper mServiceLooper;
    private ServiceHandler mServiceHandler;

    // Handler that receives messages from the thread
    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            // empty
        }
    }

    @Override
    public void onCreate() {
        // Start up the thread running the service. Note that we create a
        // separate thread because the service normally runs in the process's
        // main thread, which we don't want to block. We also make it
        // background priority so CPU-intensive work will not disrupt our UI.
        HandlerThread thread = new HandlerThread("ServiceStartArguments",
                android.os.Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();

        // Get the HandlerThread's Looper and use it for our Handler
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);

        Log.d("SERVICE TEST onCreate", "Service created first time");
        Toast.makeText(this, "service created", Toast.LENGTH_SHORT).show();
        final long oneMinuteMs = 60 * 1000;
        Runnable eachMinute = new Runnable() {
            @Override
            public void run() {
                Log.d("SERVICE TEST run", "Each minute task executing");
                mServiceHandler.postDelayed(this, oneMinuteMs);
            }
        };

        mServiceHandler.postDelayed(eachMinute, oneMinuteMs);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // empty
        // If we get killed, after returning from here, restart
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // We don't provide binding, so return null
        return null;
    }

    @Override
    public void onDestroy() {
        Log.d("SERVICE TEST onDestroy", "Service destroyed");
    }
}
  • Is this the better way in Android? 这是Android中更好的方法吗?
  • Is it correct to use onCreate method to ensure one single sync task will be started for the duration of the app life? 使用onCreate方法来确保在应用程序生命周期内启动一个同步任务是否正确?
  • Is it correct to start the service from my first activity (MainActivity)? 从我的第一个活动(MainActivity)启动服务是否正确?

The code: 编码:

package com.ncfsistemi.testservice;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this, HelloService.class);
        startService(intent);       
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

Note: I've also tried with 注意:我也尝试过

TimerTask syncTask = new TimerTask()

but I've got some strange behaviour (task spawned multiple times and with wrong time control). 但我有一些奇怪的行为(任务多次生成且时间控制错误)。 TimerTask is discouraged by Android creators... correct? Android创建者不鼓励TimerTask ...对吗?

If you want to sync data periodically based on some schedule, the best approach is to use SyncAdapter . 如果要根据某些时间表定期同步数据,最好的方法是使用SyncAdapter Take a look at the documentation, there are good examples how to use it. 看一下文档,有很好的示例如何使用它。

If you want to sync the data on demand (for example on activity's onResume method), you can use an IntentService . 如果要按需同步数据(例如,按活动的onResume方法),则可以使用IntentService

No matter what you do, do not run TimerTask . 无论您做什么,都不要运行TimerTask As you have found by yourself, unexpected behavior may occur. 正如您自己发现的那样,可能会发生意外的行为。 You can read here about how processes and threads are managed under Android OS and see that it is likely the TimerTask to be killed. 您可以在此处阅读有关在Android OS下如何管理进程和线程的信息,并发现TimerTask很可能被杀死。 For http opperations you have to use Service s because of their high priority. 对于http操作,您必须使用Service因为它们具有较高的优先级。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM