我已经制作了一个apache thrift服务器,我有一个包含多个功能的服务。 我想弄清楚从我的Android应用程序调用远程服务器的最佳方法是什么。
我的问题是我无法从MainActivity线程(主线程)进行调用 - 我需要在主要活动方法中使用大多数远程函数。
我尝试使用名为“Server”的静态memeber创建一个静态类,等于服务器对象,然后我将其设置在另一个线程中,然后我尝试在主线程(主要活动类)中调用它 - 但是因为从一个线程跳到另一个线程我有错误。
更明确地说我需要这样的东西:
public class MainActivity extends Activity {
private service.Client myService;
@Override
protected void onCreate(Bundle savedInstanceState) {
..
... Some stuff that define myService (In a new thread ofcourse) ...
}
...
private void MyFunc1() {
myService.Method1();
}
private void MyFunc2() {
myService.Method2();
}
private void MyFunc3() {
myService.Method3();
}
}
感谢您的帮助!
答案 0 :(得分:1)
我有一个用于与REST API交流的库。随意切片,切块和重复使用:https://github.com/nedwidek/Android-Rest-API
代码是BSD或GPL。
这是我如何使用我所拥有的(我已经修剪了一点MainActivity,希望不会太多):
package com.hatterassoftware.voterguide.api;
import java.util.HashMap;
public class GoogleCivicApi {
protected final String baseUrl = "https://www.googleapis.com/civicinfo/us_v1/";
protected String apiKey = "AIzaSyBZIP5uY_fMF35SVVrytpKgHtppBbj8J0I";
public static final String DATE_FORMAT = "yyyy-MM-dd";
protected static HashMap<String, String> headers;
static {
headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
}
public String createUrl(String uri, HashMap<String, String> params) {
String url = baseUrl + uri + "?key=" + apiKey;
if (params != null) {
for (String hashKey: params.keySet()) {
url += hashKey + "=" + params.get(hashKey) + "&";
}
url = url.substring(0, url.length());
}
return url;
}
}
package com.hatterassoftware.voterguide.api;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.hatterassoftware.restapi.GetTask;
import com.hatterassoftware.restapi.HttpReturn;
import com.hatterassoftware.restapi.RestCallback;
import com.hatterassoftware.voterguide.api.callbacks.ElectionCallback;
import com.hatterassoftware.voterguide.api.models.Election;
public class ElectionsQuery extends GoogleCivicApi implements RestCallback {
GetTask getTask;
ElectionCallback callback;
final String TAG = "ElectionQuery";
public ElectionsQuery(ElectionCallback callback) {
String url = this.createUrl("elections", null);
this.callback = callback;
Log.d(TAG, "Creating and executing task for: " + url);
getTask = new GetTask(url, this, null, null, null);
getTask.execute();
}
@Override
public void onPostSuccess() {
Log.d(TAG, "onPostSuccess entered");
}
@Override
public void onTaskComplete(HttpReturn httpReturn) {
Log.d(TAG, "onTaskComplete entered");
Log.d(TAG, "httpReturn.status = " + httpReturn.status);
if (httpReturn.content != null) Log.d(TAG, httpReturn.content);
if (httpReturn.restException != null) Log.d(TAG, "Exception in httpReturn", httpReturn.restException);
JsonParser parser = new JsonParser();
JsonElement electionArrayJson = ((JsonObject)parser.parse(httpReturn.content)).get("elections");
Log.d(TAG, electionArrayJson.toString());
Gson gson = new GsonBuilder().setDateFormat(GoogleCivicApi.DATE_FORMAT).create();
Election[] elections = gson.fromJson(electionArrayJson.toString(), Election[].class);
callback.retrievedElection(elections);
}
}
package com.hatterassoftware.voterguide;
import java.util.Calendar;
import java.util.List;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.hatterassoftware.voterguide.api.ElectionsQuery;
import com.hatterassoftware.voterguide.api.VoterInfoQuery;
import com.hatterassoftware.voterguide.api.callbacks.ElectionCallback;
import com.hatterassoftware.voterguide.api.callbacks.VoterInfoCallback;
import com.hatterassoftware.voterguide.api.models.Election;
import com.hatterassoftware.voterguide.api.models.VoterInfo;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends SherlockFragmentActivity implements ElectionCallback, VoterInfoCallback {
private ProgressBar mProgressBar;
public Button submit;
public Spinner state;
public Spinner election;
public EditText address;
public EditText city;
public EditText zip;
private int count=0;
private Object lock = new Object();
private static final String TAG = "MainActivity";
public static final String VOTER_INFO = "com.hatterassoftware.voterguide.VOTER_INFO";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = (ProgressBar) findViewById(R.id.home_progressBar);
Resources res = getResources();
SharedPreferences mPrefs = getApplicationSharedPreferences();
ImageButton gpsButton = (ImageButton) findViewById(R.id.locate);
try {
LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if (!manager.isProviderEnabled(Context.LOCATION_SERVICE)) {
gpsButton.setClickable(false);
}
} catch(Exception e) {
Log.d(TAG, e.getMessage(), e);
gpsButton.setClickable(false);
gpsButton.setEnabled(false);
}
submit = (Button) findViewById(R.id.submit);
submit.setClickable(false);
submit.setEnabled(false);
state = (Spinner) findViewById(R.id.state);
election = (Spinner) findViewById(R.id.election);
address = (EditText) findViewById(R.id.streetAdress);
city = (EditText) findViewById(R.id.city);
zip = (EditText) findViewById(R.id.zip);
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
doSubmit();
}
});
gpsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
doLocate();
}
});
// Let's check for network connectivity before we get down to business.
if (Utils.isNetworkAvailable(this, true)) {
// Show the disclaimer on first run.
if(mPrefs.getBoolean("firstRun", true)) {
AlertDialog alert = new AlertDialog.Builder(this).create();
alert.setCancelable(false);
alert.setTitle(res.getString(R.string.welcome));
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog, null);
TextView alertContents = (TextView) layout.findViewById(R.id.custom_dialog_text);
alertContents.setMovementMethod(LinkMovementMethod.getInstance());
alertContents.setText(Html.fromHtml(res.getString(R.string.welcome_dialog_text)));
alert.setView(alertContents);
alert.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SharedPreferences mPrefs = getApplicationSharedPreferences();
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean("firstRun", false);
editor.commit();
dialog.dismiss();
retrieveElections();
}
});
alert.show();
} else {
retrieveElections();
}
}
}
@Override
public void onResume() {
super.onResume();
// Let's check for network connectivity before we get down to business.
Utils.isNetworkAvailable(this, true);
LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if (!(manager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|| manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) {
Toast.makeText(this, "GPS is not available", 2).show();
ImageButton gpsButton = (ImageButton) findViewById(R.id.locate);
gpsButton.setClickable(false);
}
}
public SharedPreferences getApplicationSharedPreferences() {
Context mContext = this.getApplicationContext();
return mContext.getSharedPreferences("com.hatterassoftware.voterguide", MODE_PRIVATE);
}
private void showSpinner() {
synchronized(lock) {
count++;
mProgressBar.setVisibility(View.VISIBLE);
}
}
private void hideSpinner() {
synchronized(lock) {
count--;
if(count < 0) { // Somehow we're trying to hide it more times than we've shown it.
count=0;
}
if (count == 0) {
mProgressBar.setVisibility(View.INVISIBLE);
}
}
}
public void retrieveElections() {
Log.d(TAG, "Retrieving the elections");
showSpinner();
ElectionsQuery query = new ElectionsQuery(this);
}
@Override
public void retrievedElection(Election... elections) {
Log.d(TAG, "Retrieved the elections");
hideSpinner();
for (int i=0; i<elections.length; i++) {
Log.d(TAG, elections[i].toString());
}
ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, elections);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner spinner = (Spinner) this.findViewById(R.id.election);
spinner.setAdapter(arrayAdapter);
}
}