2013-01-18 168 views
-1

我製作了一個apache節儉服務器,並且我有一個包含多個功能的服務。 我想弄清楚什麼是從我的android應用程序調用遠程服務器的最佳方式。在Android應用程序中進行遠程服務器調用

我的問題是,我不能從MainActivity線程(主線程)調用 - 我需要在我的主要活動方法中使用大部分遠程函數。我試圖用一個名爲「Server」的靜態成員等於服務器對象來創建一個靜態類,並將其設置在另一個線程中,然後我試圖在主線程(主要活動類)中調用它 - 但我不得不從一個線程,因爲跳躍的錯誤,另一個..

要更加specifed我想這樣的事情:

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

感謝幫助!

回答

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

    } 
} 
+0

感謝您的幫助 - 但我很抱歉,我不能從這個不懂代碼..你可以嘗試解釋我的代碼的步驟? – Dave

+0

是的,這對於進行RESTful調用有點特別。基本要點是你不能在UI線程上進行網絡調用。你需要在AsyncTask中完成。所以你需要創建自己的類來擴展AsyncTask(以GetTask爲例)。然後,您還需要能夠在數據準備就緒時收集數據。所以你創建了一個回調接口(如RestCallback)。所以GetTask.execute()開始調用doInBackground()是在新線程上做的工作。 onPostExecute()在工作結束後運行。這將調用回調方法。 –

+0

你的活動實現你的回調接口並捕獲數據。 –

相關問題