gpt4 book ai didi

android - RESTful API 服务

转载 作者:IT老高 更新时间:2023-10-28 12:52:33 30 4
gpt4 key购买 nike

我正在寻找一种可以用来调用基于 Web 的 REST API 的服务。

基本上我想在 app init 上启动一个服务,然后我希望能够要求该服务请求一个 url 并返回结果。与此同时,我希望能够显示一个进度窗口或类似的东西。

我已经创建了一个当前使用 IDL 的服务,我在某处读到你只需要它来进行跨应用程序通信,所以认为这些需要去掉但不确定如何在没有它的情况下进行回调。此外,当我点击 post(Config.getURL("login"), values) 时,应用程序似乎暂停了一段时间(似乎很奇怪 - 认为服务背后的想法是它运行在不同的线程!)

目前我有一个服务,其中包含 post 和 get http 方法、几个 AIDL 文件(用于双向通信)、一个 ServiceManager 处理启动、停止、绑定(bind)等服务,我正在动态创建一个处理程序根据需要为回调提供特定代码。

我不希望任何人给我一个完整的代码库来工作,但我们将不胜感激。

(大部分)完整的代码:

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;
}
}

服务初始化和绑定(bind):

// 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);
}

}

};

最佳答案

如果您的服务将成为您应用程序的一部分,那么您将使它变得比它需要的复杂得多。由于您有一个从 RESTful Web 服务获取一些数据的简单用例,您应该查看 ResultReceiverIntentService .

此服务 + ResultReceiver 模式通过使用 startService() 启动或绑定(bind)到服务来工作。当你想做一些 Action 时。您可以指定要执行的操作,并通过 Intent 中的 extras 传入您的 ResultReceiver( Activity )。

在您实现的服务中onHandleIntent执行 Intent 中指定的操作。操作完成后,您使用传入的 ResultReceiver 到 send一条消息返回到 Activity 点onReceiveResult将被调用。

例如,您想从 Web 服务中提取一些数据。

  1. 您创建 Intent 并调用 startService。
  2. 服务中的操作启动,并向 Activity 发送一条消息,说明它已启动
  3. Activity 处理消息并显示进度。
  4. 服务完成操作并将一些数据发送回您的 Activity 。
  5. 您的 Activity 处理数据并放入 ListView 中
  6. 该服务会向您发送一条消息,说它已完成,它会自行终止。
  7. Activity 获取完成消息并隐藏进度对话框。

我知道您提到您不想要代码库,而是想要开源 Google I/O 2010应用程序以我所描述的这种方式使用服务。

更新为添加示例代码:

Activity 。

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;
}
}

服务:

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 扩展 - 已编辑以实现 MyResultReceiver.Receiver

public class MyResultReceiver implements 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);
}
}
}

关于android - RESTful API 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3197335/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com