ฉันกำลังมองหาบริการที่สามารถใช้โทรหา REST API บนเว็บได้
โดยทั่วไปฉันต้องการเริ่มบริการบนแอพ init แล้วฉันต้องการที่จะสามารถขอบริการนั้นเพื่อขอ URL และส่งคืนผลลัพธ์ ในระหว่างนี้ฉันต้องการแสดงหน้าต่างความคืบหน้าหรือบางอย่างที่คล้ายกัน
ตอนนี้ฉันได้สร้างบริการที่ใช้ IDL แล้วฉันได้อ่านบางที่ที่คุณต้องการสำหรับการสื่อสารข้ามแอพดังนั้นคิดว่าสิ่งเหล่านี้ต้องการการลอกออก แต่ไม่แน่ใจว่าจะโทรกลับโดยไม่ใช้มันได้อย่างไร นอกจากนี้เมื่อฉันตีpost(Config.getURL("login"), values)
แอพดูเหมือนว่าจะหยุดชั่วขณะหนึ่ง (ดูเหมือนแปลก - คิดว่าความคิดที่อยู่เบื้องหลังบริการคือมันทำงานบนเธรดที่แตกต่างกัน!)
ขณะนี้ฉันมีบริการที่มีการโพสต์และรับวิธีการ HTTP ภายใน, ไฟล์ AIDL สองไฟล์ (สำหรับการสื่อสารสองทาง), ServiceManager ซึ่งเกี่ยวข้องกับการเริ่มต้น, หยุด, ผูก ฯลฯ กับบริการและฉันกำลังสร้างตัวจัดการด้วยรหัสเฉพาะแบบไดนามิก สำหรับการโทรกลับตามความจำเป็น
ฉันไม่ต้องการให้ใครให้รหัสฐานที่สมบูรณ์แก่ฉันเพื่อการทำงาน แต่พอยน์เตอร์บางตัวจะได้รับการชื่นชมอย่างมาก
รหัสเต็ม (ส่วนใหญ่) เต็ม:
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) {...}
};
ไฟล์ AIDL สองสามไฟล์:
package com.something.android
oneway interface IRemoteServiceCallback {
void userLogIn(String result);
}
และ
package com.something.android
import com.something.android.IRemoteServiceCallback;
interface IRestfulService {
void doLogin(in String username, in String password);
void registerCallback(IRemoteServiceCallback cb);
}
และผู้จัดการบริการ:
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 และผูก:
// this I'm calling on app onCreate
servicemanager = new ServiceManager(this);
servicemanager.startService();
servicemanager.bindService();
application = (ApplicationState)this.getApplication();
application.setServiceManager(servicemanager);
ฟังก์ชั่นบริการโทร:
// 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);
}
}
};