SORU
7 Temmuz 2010, ÇARŞAMBA


Dinlendirici bir API hizmeti

Web tabanlı REST API için arama yapmak için kullanabileceğiniz bir hizmet yapmak için arıyorum.

Temelde bu hizmeti bir url istemek için sormak istiyorum, sonra app ınıt bir hizmeti başlatmak ve sonuçları geri dönmek istiyorum. Bu arada ilerleme bir pencere ya da benzer bir şey görüntülemek için mümkün olmak istiyorum.

SERVİSLER kullanan bir hizmeti şu anda yarattığım, sadece çapraz uygulama iletişim kurmaya ihtiyacı olduğunu okumuştum, o olmadan geri aramalar yapmak için nasıl bu ihtiyaçları sıyırma ama emin düşünüyorum. Ayrıca post(Config.getURL("login"), values) bastığımda uygulamayı bir süre (garip görünüyor - bir hizmet arkasındaki fikir, farklı bir iş parçacığı üzerinde çalışan olduğunu düşündüm!) için duraklama gibi görünüyor

Şu anda elimde bir hizmet ile post ve http get yöntemleri içinde, birkaç AİDL dosyaları (iki yönlü iletişim), ServiceManager hangi fırsatlar ile başlatma, durdurma, bağlama vb hizmet ve ben dinamik olarak oluşturma İşleyicisi ile belirli bir kod için geri aramaları gerektiği gibi.

Kimse bana üzerinde çalışmak için tam bir kod tabanı vermek istemiyorum, ama bazı noktalar büyük mutluluk duyacağız.

(Çoğunlukla) tam kod:

public class RestfulAPIService extends Service  {

final RemoteCallbackList<IRemoteServiceCallback> mCallbacks = new RemoteCallbackList<IRemoteServiceCallback>();

public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
}
public IBinder onBind(Intent intent) {
    return binder;
}
public void onCreate() {
    super.onCreate();
}
public void onDestroy() {
    super.onDestroy();
    mCallbacks.kill();
}
private final IRestfulService.Stub binder = new IRestfulService.Stub() {
    public void doLogin(String username, String password) {

        Message msg = new Message();
        Bundle data = new Bundle();
        HashMap<String, String> values = new HashMap<String, String>();
        values.put("username", username);
        values.put("password", password);
        String result = post(Config.getURL("login"), values);
        data.putString("response", result);
        msg.setData(data);
        msg.what = Config.ACTION_LOGIN;
        mHandler.sendMessage(msg);
    }

    public void registerCallback(IRemoteServiceCallback cb) {
        if (cb != null)
            mCallbacks.register(cb);
    }
};

private final Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {

        // Broadcast to all clients the new value.
        final int N = mCallbacks.beginBroadcast();
        for (int i = 0; i < N; i  ) {
            try {
                switch (msg.what) {
                case Config.ACTION_LOGIN:
                    mCallbacks.getBroadcastItem(i).userLogIn( msg.getData().getString("response"));
                    break;
                default:
                    super.handleMessage(msg);
                    return;

                }
            } catch (RemoteException e) {
            }
        }
        mCallbacks.finishBroadcast();
    }
    public String post(String url, HashMap<String, String> namePairs) {...}
    public String get(String url) {...}
};

AİDL bir kaç dosya:

package com.something.android

oneway interface IRemoteServiceCallback {
    void userLogIn(String result);
}

ve

package com.something.android
import com.something.android.IRemoteServiceCallback;

interface IRestfulService {
    void doLogin(in String username, in String password);
    void registerCallback(IRemoteServiceCallback cb);
}

servis yöneticisi:

public class ServiceManager {

    final RemoteCallbackList<IRemoteServiceCallback> mCallbacks = new RemoteCallbackList<IRemoteServiceCallback>();
    public IRestfulService restfulService;
    private RestfulServiceConnection conn;
    private boolean started = false;
    private Context context;

    public ServiceManager(Context context) {
        this.context = context;
    }

    public void startService() {
        if (started) {
            Toast.makeText(context, "Service already started", Toast.LENGTH_SHORT).show();
        } else {
            Intent i = new Intent();
            i.setClassName("com.something.android", "com.something.android.RestfulAPIService");
            context.startService(i);
            started = true;
        }
    }

    public void stopService() {
        if (!started) {
            Toast.makeText(context, "Service not yet started", Toast.LENGTH_SHORT).show();
        } else {
            Intent i = new Intent();
            i.setClassName("com.something.android", "com.something.android.RestfulAPIService");
            context.stopService(i);
            started = false;
        }
    }

    public void bindService() {
        if (conn == null) {
            conn = new RestfulServiceConnection();
            Intent i = new Intent();
            i.setClassName("com.something.android", "com.something.android.RestfulAPIService");
            context.bindService(i, conn, Context.BIND_AUTO_CREATE);
        } else {
            Toast.makeText(context, "Cannot bind - service already bound", Toast.LENGTH_SHORT).show();
        }
    }

    protected void destroy() {
        releaseService();
    }

    private void releaseService() {
        if (conn != null) {
            context.unbindService(conn);
            conn = null;
            Log.d(LOG_TAG, "unbindService()");
        } else {
            Toast.makeText(context, "Cannot unbind - service not bound", Toast.LENGTH_SHORT).show();
        }
    }

    class RestfulServiceConnection implements ServiceConnection {
        public void onServiceConnected(ComponentName className, IBinder boundService) {
            restfulService = IRestfulService.Stub.asInterface((IBinder) boundService);
            try {
            restfulService.registerCallback(mCallback);
            } catch (RemoteException e) {}
        }

        public void onServiceDisconnected(ComponentName className) {
            restfulService = null;
        }
    };

    private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {
        public void userLogIn(String result) throws RemoteException {
            mHandler.sendMessage(mHandler.obtainMessage(Config.ACTION_LOGIN, result));

        }
    };

    private Handler mHandler;

    public void setHandler(Handler handler) {
        mHandler = handler;
    }
}

Init ve bağlama servisi:

// this I'm calling on app onCreate
servicemanager = new ServiceManager(this);
servicemanager.startService();
servicemanager.bindService();
application = (ApplicationState)this.getApplication();
application.setServiceManager(servicemanager);

işlev çağrı servis:

// this lot i'm calling as required - in this example for login
progressDialog = new ProgressDialog(Login.this);
progressDialog.setMessage("Logging you in...");
progressDialog.show();

application = (ApplicationState) getApplication();
servicemanager = application.getServiceManager();
servicemanager.setHandler(mHandler);

try {
    servicemanager.restfulService.doLogin(args[0], args[1]);
} catch (RemoteException e) {
    e.printStackTrace();
}

...later in the same file...

Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {

        switch (msg.what) {
        case Config.ACTION_LOGIN:

            if (progressDialog.isShowing()) {
                progressDialog.dismiss();
            }

            try {
                ...process login results...
                }
            } catch (JSONException e) {
                Log.e("JSON", "There was an error parsing the JSON", e);
            }
            break;
        default:
            super.handleMessage(msg);
        }

    }

};

CEVAP
7 Temmuz 2010, ÇARŞAMBA


Eğer hizmetiniz bir uygulamanın parçası olacaksa o zaman bunu olması gerekenden çok fazla daha karmaşık hale getiriyorsun. Dinlendirici bir Web servisinden bir veri almak için basit bir senaryo olduğu, ResultReceiver IntentService içine bakmak gerekir.

Bu Hizmet ResultReceiver desen biraz hareket yapmak istediğinizde startService() ile hizmete başlayan veya bağlanarak çalışır. Gerçekleştirmek ve ResultReceiver (etkinlik) Niyet figüranlar üzerinden geçmek operasyon belirtebilirsiniz.

Hizmeti onHandleIntent Niyet belirtilen işlemi yapmak için uygulamak. İşlem tamamlandığında send ResultReceiver bir mesaj hangi noktada onReceiveResult adı verilecek olan Etkinlik için geri geçti kullanın.

Yani, örneğin, Web servisinden bir veri çekmek istiyorum.

  1. Niyet ve çağrı startService oluşturun.
  2. Servis işlemi başlar ve faaliyet bir mesaj vermeye değmez gönderir
  3. Etkinlik iletisini işler ve bir ilerleme gösterir.
  4. Servis işlemi tamamlanır ve etkinliği için geri gönderir.
  5. Aktivite verileri işler ve bir liste görünümünde koyar
  6. Servis bir mesaj yapılır söyleyerek gönderir ve kendini öldürür.
  7. Etkinlik bitiş mesajı alır ve ilerleme iletişim gizler.

Kod tabanı ama Google I/O 2010 uygulama benim anlattığım bu şekilde bir hizmeti kullanan açık kaynak istemediğini söylemiştin.

Güncelleştirilmiş örnek kod eklemek için:

Faaliyet.

public class HomeActivity extends Activity implements MyResultReceiver.Receiver {

    public MyResultReceiver mReceiver;

    public void onCreate(Bundle savedInstanceState) {
        mReceiver = new MyResultReceiver(new Handler());
        mReceiver.setReceiver(this);
        ...
        final Intent intent = new Intent(Intent.ACTION_SYNC, null, this, QueryService.class);
        intent.putExtra("receiver", mReceiver);
        intent.putExtra("command", "query");
        startService(intent);
    }

    public void onPause() {
        mReceiver.setReceiver(null); // clear receiver so no leaks.
    }

    public void onReceiveResult(int resultCode, Bundle resultData) {
        switch (resultCode) {
        case RUNNING:
            //show progress
            break;
        case FINISHED:
            List results = resultData.getParcelableList("results");
            // do something interesting
            // hide progress
            break;
        case ERROR:
            // handle the error;
            break;
    }
}

Hizmet:

public class QueryService extends IntentService {
    protected void onHandleIntent(Intent intent) {
        final ResultReceiver receiver = intent.getParcelableExtra("receiver");
        String command = intent.getStringExtra("command");
        Bundle b = new Bundle();
        if(command.equals("query") {
            receiver.send(STATUS_RUNNING, Bundle.EMPTY);
            try {
                // get some data or something           
                b.putParcelableArrayList("results", results);
                receiver.send(STATUS_FINISHED, b)
            } catch(Exception e) {
                b.putString(Intent.EXTRA_TEXT, e.toString());
                receiver.send(STATUS_ERROR, b);
            }    
        }
    }
}

ResultReceiver uzantısı - MyResultReceiver uygulamak üzere düzenlenmiş.Alıcı

public MyResultReceiver extends ResultReceiver {
    private Receiver mReceiver;

    public MyResultReceiver(Handler handler) {
        super(handler);
    }

    public void setReceiver(Receiver receiver) {
        mReceiver = receiver;
    }

    public interface Receiver {
        public void onReceiveResult(int resultCode, Bundle resultData);
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        if (mReceiver != null) {
            mReceiver.onReceiveResult(resultCode, resultData);
        }
    }
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Miles Fisher

    Miles Fisher

    8 NİSAN 2009
  • SegaAmerica

    SegaAmerica

    5 Mart 2008
  • thetrollska

    thetrollska

    2 EKİM 2009