简体   繁体   中英

Making remote server calls in an Android application

I've made an apache thrift server and I have a service which contains several functions. I'm trying to figure out what is the best way to make calls to the remote server from my android application.

My problem is that I can't make calls from the MainActivity thread (the main thread) - and I need to use most of the remote functions in my main activity methods.

I tried to make a static class with a static member called "Server" equals to the server object, and I set it in another thread and then I tried to call it in the main thread (the main activity class) - but I had errors because of jumping from one thread to another..

To be more specified I want something like that:

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

I've got a library for talking to REST APIs. Feel free to slice, dice, and re-use: https://github.com/nedwidek/Android-Rest-API

The code is BSD or GPL.

Here's how I use what I have (I've trimmed MainActivity a bit, hopefully not too much):

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

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM