永远不会在服务中调用onBind() [英] onBind() is never called in a service

查看:67
本文介绍了永远不会在服务中调用onBind()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写具有绑定服务的基于服务的应用程序,并且似乎从未调用过该服务的onBind()方法(使用Toasts和Logs对其进行测试).

I am writing a service based app with a bound service, and the service's onBind() method never seems to be called (testing it with Toasts and Logs).

服务:

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import com.gmail.zack.yovel.FlickAround.MyActivity;
import com.gmail.zack.yovel.FlickAround.R;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;

/**
 * Created with IntelliJ IDEA.
 * User: Ziky
 * Date: 09/04/13
 * Time: 19:06
 * To change this template use File | Settings | File Templates.
 */
public class UpdateService extends Service implements LocationListener, UpdatePhotosTask.OnHttpResponseListener {
    private final static String API_KEY = "5255c7b02750c0fa4b15bd8ad4ec1fb7";
    private final static String GET_PHOTOS_FOR_LOCATION_SCHEMA = "http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=" + API_KEY + "&lat=%d&lon=%d&format=json&nojsoncallback=1";
    private static final String KEY_PHOTOS = "photos";
    private static final String KEY_PHOTO = "photo";
    private int NOTIFICATION = R.string.update_service_started;
    private NotificationManager mNManager;
    private LocationManager mLManager;
    private String mProvider;
    private Location mLocation;
    private IBinder mBinder = new LocalBinder();
    private UpdatePhotosTask task;

    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(this, "UpdateService.onBind()", Toast.LENGTH_LONG).show();
        Log.i("test", "UpdateService.onBind()");
        mLManager.requestLocationUpdates(mProvider, 0, 1000, this);
        return mBinder;
    }

    @Override
    public void onCreate() {
        mNManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        showNotification();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("LocalService", "Received start id " + startId + ": " + intent);
        mLManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        mProvider = mLManager.getBestProvider(criteria, false);
        mLocation = mLManager.getLastKnownLocation(mProvider);
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        mNManager.cancel(NOTIFICATION);
        Toast.makeText(this, R.string.update_service_stoped, Toast.LENGTH_SHORT).show();
    }

    private void showNotification() {
        CharSequence text = getText(R.string.update_service_active);
        Notification notification = new Notification(R.drawable.refresh, text, System.currentTimeMillis());
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MyActivity.class), 0);
        notification.setLatestEventInfo(this, getText(R.string.update_service_label), text, contentIntent);
        mNManager.notify(NOTIFICATION, notification);
    }

    @Override
    public void onLocationChanged(Location location) {
        beginUpdate(location);
    }

    private void beginUpdate(Location location) {
        Toast.makeText(this, "beginning update", Toast.LENGTH_LONG).show();
        String url = buildUrl(location);
        task = new UpdatePhotosTask(this);
        task.execute(url);
    }

    private String buildUrl(Location location) {
        return String.format(GET_PHOTOS_FOR_LOCATION_SCHEMA, location.getLatitude(), location.getLongitude());
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onHttpResponse(ArrayList<String> responses) {
        if (responses.size() > 0) {
            String response = responses.get(0);
            try {
                JSONObject jsonObject = new JSONObject(response);
                jsonObject = jsonObject.getJSONObject(KEY_PHOTOS);
                JSONArray jsonArray = jsonObject.getJSONArray(KEY_PHOTO);
                ArrayList<String> photos = new ArrayList<String>();
                for (int i = 0, length = jsonArray.length(); i < length; i++) {
                    jsonObject = jsonArray.getJSONObject(i);
                    Log.i("photo info", jsonObject.toString());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

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

AsyncTask:

The AsyncTask:

import android.os.AsyncTask;
import android.util.Log;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

/**
 * Created with IntelliJ IDEA.
 * User: Ziky
 * Date: 09/04/13
 * Time: 07:38
 * To change this template use File | Settings | File Templates.
 */
public class UpdatePhotosTask extends AsyncTask<String, Void, ArrayList<String>> {

    private OnHttpResponseListener listener;

    public UpdatePhotosTask(OnHttpResponseListener listener) {
        this.listener = listener;
    }

    @Override
    protected ArrayList<String> doInBackground(String... urls) {
        ArrayList<String> responses = new ArrayList<String>();
        for (String url : urls) {
            StringBuilder response = new StringBuilder();
            DefaultHttpClient client = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            try {
                HttpResponse execute = client.execute(httpGet);
                StatusLine statusLine = execute.getStatusLine();
                int statusCode = statusLine.getStatusCode();
                if (statusCode == 200) {
                    InputStream content = execute.getEntity().getContent();
                    BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
                    String s = "";
                    while ((s = buffer.readLine()) != null) {
                        response.append(s);
                    }
                    responses.add(response.toString());
                } else {
                    Log.e(this.getClass().toString(), "Failed to download photo list");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responses;
    }

    @Override
    protected void onPostExecute(ArrayList<String> responses) {
        listener.onHttpResponse(responses);
    }

    public interface OnHttpResponseListener {
        public void onHttpResponse(ArrayList<String> responses);
    }
}

活动:

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.StrictMode;
import android.widget.Toast;
import com.gmail.zack.yovel.FlickAround.background.UpdateService;

public class MyActivity extends Activity {
    private UpdateService mUpdateService;
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mUpdateService = ((UpdateService.LocalBinder) service).getService();
            Toast.makeText(MyActivity.this, R.string.update_service_connected, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mUpdateService = null;
            Toast.makeText(MyActivity.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show();
        }
    };
    private boolean mIsBound;

    void doBindService() {
        Toast.makeText(this, "MyActivity.doBindService()", Toast.LENGTH_LONG).show();
        bindService(new Intent(this, UpdateService.class), mConnection, BIND_AUTO_CREATE);
        mIsBound = true;
    }

    void doUnbindService() {
        if (mIsBound) {
            unbindService(mConnection);
            mIsBound = false;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        doUnbindService();
    }

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Activate StrictMode
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectAll().penaltyLog().penaltyDeath().build());
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
                .penaltyLog().penaltyDeath().build());
    }

    @Override
    protected void onStart() {
        super.onStart();
        doBindService();
    }
}

为什么不起作用?

推荐答案

最常见的无提示绑定失败源可能是清单中没有列出服务.这不会引发异常,因此您的应用程序不会崩溃,但是LogCat中应该有一条消息(警告,IIRC)指出您的问题.

Probably the most common source of binding silently failing is not having the service listed in the manifest. This does not raise an exception, so your app does not crash, but there should be a message (warning, IIRC) in LogCat pointing out your issue.

这篇关于永远不会在服务中调用onBind()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆