4

I have following server Urls:

server-base-url/method1
server-base-url/method2
server-base-url/method3
...
server-base-url/method100

I am currently using a properties file to store the URLs. When I need to consume some of the server URLs, then I read the properties file and perform the http request using Spring 4 Android

I know that should be another way (and a better way) to do this. What is the best practice to achieve this?

4

4 回答 4

3

Definitely I will go with android resources under values as string. so you name it once and get benefit of the powerful tools from Android studio for customization and localization by Locale, buildtype, and flavors... I just would suggest to set urls in separated file. i.e. urls.xml

    <resources>
        <string name="url_server1">http://apipas.com/gloabl/server1</string>
        <string name="url_server2">http://apipas.com/global/server2</string>
    </resources>

For simple project it might not matter.. but when you are dealing wth an enterprise one,or with multiple targets, multiple-language, different server tiers (based on location;EU/Asia... , or on usage:free/paid, or on phase:dev/testing/production) it will be crucial what way you select to manage such as resources.

Let me elaborate that... lets say we have this build.gradle for app:

buildTypes {
    debug {
        debuggable false
        applicationIdSuffix 'debug'
    }
    qa {
        debuggable false
        applicationIdSuffix 'qa'
    }
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

productFlavors {
    paid {
        applicationId = "com.apipas.android.wellmanagerurlsapp.paid"
    }
    free {
        applicationId = "com.apipas.android.wellmanagerurlsapp.free"
    }
}

Also it supports de as german language and Australian locale en-rAU

So we have these customization factors:

  • Flavor : paid/free ( it can be something else: CPU arch,regions,... etc)
  • BuildType: in addition to Release and Debug I added QA to test app with testing server if available.
  • Locales: base,de, & en-rAU

All what you need to do is just to override res in correct location that fulfills what you need to achieve

Lets say I'd to use buildType base to customize URLS :

enter image description here

Or you'd use Flavors:

enter image description here

Be aware not to fall with duplication when use flavor and buildType together to customize res.

Along developing, you dont need to change the name of url.. this is really a good point when you have big project. still you can change content easily for any flavor/buildType/locale

You can also use JSON, XML, or properties as you referred. but none of them will give you what res do.

Good luck,'.

于 2016-03-05T10:11:21.143 回答
1

Another Option is to use Plain Java:

public class ServerInfo {
     private static final String URL_BASE_DEBUG = "your base debug url";
     private static final String URL_BASE_RELEASE = "your base release url";

     public static String getBaseUrl() {
          //change if debug' release or whichever flavor
          return URL_BASE_DEBUG;
     } 
}

It's pretty straight forward...You can have all the information needed in a single Java Class

Now regarding the network comm It's really up to you...There are many choices...I personally like Retrofit 2 which is a wrapper on top of a networking library okhttp

A short example of how you can use Retrofit with the above method is:

Rest Api (like User Rest api)

public interface SomeRestApiEndPoints {
    @GET("api/method1")
    Call<ReturnValue> method1(params);

    @POST(api/method2)
    Call<ReturnObject> method2(params);
    ...
}

The Rest Client

public class RestClient {
   private static RestClient sRestClient;

   private Retrofit mRetrofit;
   private SomeRestApiEndPoints apiEndpoint;

   public static RestClient getRestClient () {
        if(sRestClient != null){
            return sRestClient;
        }

        synchronized (RestClient.class) {
            if(sRestClient == null) {
            //gson example
            Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
            RestClient client = new RestClient();
            client.mRetrofit = new Retrofit.Builder()
                    .baseUrl(ServerInfo.getBaseUrl()) //This is where you bind the base Url
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .build();     

            client.apiEndpoint = client.mRetrofit.create(SomeRestApiEndPoints.class);
            sRestClient = client;
        }
        return sRestClient;
    }


    public SomeRestApiEndPoints getApi() {
        return apiEndpoints;
    }

}

Usage Example

Call<ReturnValue> call = RestClient.getRestClient().getApi().method1(params);
于 2016-03-06T21:15:09.820 回答
1

What I use to do is to create the URL parameters in the build.gradle file depending on the buildType. This is the strategy followed by the great iosched project.

First thing to do is add in your gradle.propeties file your lines:

# Website hostname
dev_website_host_name = devUrl.com 
production_website_host_name = productionUrl.com 

After that in your build.gradle file this for example:

buildTypes {
    debug {
        debuggable true
        minifyEnabled false
        signingConfig signingConfigs.debug
        resValue("string", "website_host_name", "${dev_website_host_name}")
    }
    release {
        debuggable false
        minifyEnabled true
        // No signing config as we do this separately.
        proguardFiles getDefaultProguardFile('proguard-android.txt'), file('proguard-project.txt')
        resValue("string", "website_host_name", "${production_website_host_name}")
    }
}

Grade will create the string resource called website_host_name, and depending on your build type will have one value or another. To access to that value by code just type R.string.website_host_name and that's it!!

This is how I handle different build types with different environments. Google's projects are always a good reference to bear in mind.

于 2016-03-06T21:37:48.213 回答
0

A better way to do this is by using a REST API client. I would recomend you using Retrofit.

A proper guide to find out how to use it can be found here.

于 2016-03-06T19:20:43.523 回答