Giter Club home page Giter Club logo

fast-android-networking's Introduction

Fast Android Networking Library

About Fast Android Networking Library

Fast Android Networking Library is a powerful library for doing any type of networking in Android applications which is made on top of OkHttp Networking Layer.

Fast Android Networking Library takes care of each and everything. So you don't have to do anything, just make request and listen for the response.

Why use Fast Android Networking ?

  • Recent removal of HttpClient in Android Marshmallow(Android M) made other networking libraries obsolete.
  • No other single library does each and everything like making request, downloading any type of file, uploading file, loading image from network in ImageView, etc. There are some libraries but they are outdated.
  • No other library provides simple interface for doing all types of things in networking like setting priority, cancelling, etc.
  • As it uses Okio , No more GC overhead in android applications. Okio is made to handle GC overhead while allocating memory. Okio does some clever things to save CPU and memory.
  • It uses OkHttp , more importantly it supports HTTP/2.

About me

Hi, I am Amit Shekhar, Co-Founder @ Outcome School • IIT 2010-14 • I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.

You can connect with me on:

Outcome School Blog - High-quality content to learn Android concepts.

RxJava2 Support, check here.

Find this project useful ? ❤️

  • Support it by clicking the ⭐ button on the upper right of this page. ✌️

For full details, visit the documentation on our web site :

Requirements

Fast Android Networking Library can be included in any Android application.

Fast Android Networking Library supports Android 2.3 (Gingerbread) and later.

Using Fast Android Networking Library in your application

Add this in your settings.gradle:

maven { url 'https://jitpack.io' }

If you are using settings.gradle.kts, add the following:

maven { setUrl("https://jitpack.io") }

Add this in your build.gradle

implementation 'com.github.amitshekhariitbhu.Fast-Android-Networking:android-networking:1.0.4'

If you are using build.gradle.kts, add the following:

implementation("com.github.amitshekhariitbhu.Fast-Android-Networking:android-networking:1.0.4")

Do not forget to add internet permission in manifest if already not present

<uses-permission android:name="android.permission.INTERNET" />

Then initialize it in onCreate() Method of application class :

AndroidNetworking.initialize(getApplicationContext());

Initializing it with some customization , as it uses OkHttp as networking layer, you can pass custom okHttpClient while initializing it.

// Adding an Network Interceptor for Debugging purpose :
OkHttpClient okHttpClient = new OkHttpClient() .newBuilder()
                        .addNetworkInterceptor(new StethoInterceptor())
                        .build();
AndroidNetworking.initialize(getApplicationContext(),okHttpClient);                        

Using the Fast Android Networking with Jackson Parser

Add this in your build.gradle

implementation 'com.github.amitshekhariitbhu.Fast-Android-Networking:jackson-android-networking:1.0.4'

If you are using build.gradle.kts, add the following:

implementation("com.github.amitshekhariitbhu.Fast-Android-Networking:jackson-android-networking:1.0.4")
// Then set the JacksonParserFactory like below
AndroidNetworking.setParserFactory(new JacksonParserFactory());

Using the Fast Android Networking with RxJava2

Add this in your build.gradle

implementation 'com.github.amitshekhariitbhu.Fast-Android-Networking:rx2-android-networking:1.0.4'

If you are using build.gradle.kts, add the following:

implementation("com.github.amitshekhariitbhu.Fast-Android-Networking:rx2-android-networking:1.0.4")

Using the Fast Android Networking with RxJava

Add this in your build.gradle

implementation 'com.github.amitshekhariitbhu.Fast-Android-Networking:rx-android-networking:1.0.4'

If you are using build.gradle.kts, add the following:

implementation("com.github.amitshekhariitbhu.Fast-Android-Networking:rx-android-networking:1.0.4")

Making a GET Request

AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllUsers/{pageNumber}")
                 .addPathParameter("pageNumber", "0")
                 .addQueryParameter("limit", "3")
                 .addHeaders("token", "1234")
                 .setTag("test")
                 .setPriority(Priority.LOW)
                 .build()
                 .getAsJSONArray(new JSONArrayRequestListener() {
                    @Override
                    public void onResponse(JSONArray response) {
                      // do anything with response
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error
                    }
                });                

Making a POST Request

AndroidNetworking.post("https://fierce-cove-29863.herokuapp.com/createAnUser")
                 .addBodyParameter("firstname", "Amit")
                 .addBodyParameter("lastname", "Shekhar")
                 .setTag("test")
                 .setPriority(Priority.MEDIUM)
                 .build()
                 .getAsJSONObject(new JSONObjectRequestListener() {
                    @Override
                    public void onResponse(JSONObject response) {
                      // do anything with response
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error
                    }
                });

You can also post java object, json, file, etc in POST request like this.

User user = new User();
user.firstname = "Amit";
user.lastname = "Shekhar";

AndroidNetworking.post("https://fierce-cove-29863.herokuapp.com/createUser")
                 .addBodyParameter(user) // posting java object
                 .setTag("test")
                 .setPriority(Priority.MEDIUM)
                 .build()
                 .getAsJSONArray(new JSONArrayRequestListener() {
                    @Override
                    public void onResponse(JSONArray response) {
                      // do anything with response
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error
                    }
                });


JSONObject jsonObject = new JSONObject();
try {
    jsonObject.put("firstname", "Amit");
    jsonObject.put("lastname", "Shekhar");
} catch (JSONException e) {
  e.printStackTrace();
}
       
AndroidNetworking.post("https://fierce-cove-29863.herokuapp.com/createUser")
                 .addJSONObjectBody(jsonObject) // posting json
                 .setTag("test")
                 .setPriority(Priority.MEDIUM)
                 .build()
                 .getAsJSONArray(new JSONArrayRequestListener() {
                    @Override
                    public void onResponse(JSONArray response) {
                      // do anything with response
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error
                    }
                });
                
AndroidNetworking.post("https://fierce-cove-29863.herokuapp.com/postFile")
                 .addFileBody(file) // posting any type of file
                 .setTag("test")
                 .setPriority(Priority.MEDIUM)
                 .build()
                 .getAsJSONObject(new JSONObjectRequestListener() {
                    @Override
                    public void onResponse(JSONObject response) {
                      // do anything with response
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error
                    }
                });               

Using it with your own JAVA Object - JSON Parser

/*--------------Example One -> Getting the userList----------------*/
AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllUsers/{pageNumber}")
                .addPathParameter("pageNumber", "0")
                .addQueryParameter("limit", "3")
                .setTag(this)
                .setPriority(Priority.LOW)
                .build()
                .getAsObjectList(User.class, new ParsedRequestListener<List<User>>() {
                    @Override
                    public void onResponse(List<User> users) {
                      // do anything with response
                      Log.d(TAG, "userList size : " + users.size());
                      for (User user : users) {
                        Log.d(TAG, "id : " + user.id);
                        Log.d(TAG, "firstname : " + user.firstname);
                        Log.d(TAG, "lastname : " + user.lastname);
                      }
                    }
                    @Override
                    public void onError(ANError anError) {
                     // handle error
                    }
                });
/*--------------Example Two -> Getting an user----------------*/
AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAnUserDetail/{userId}")
                .addPathParameter("userId", "1")
                .setTag(this)
                .setPriority(Priority.LOW)
                .build()
                .getAsObject(User.class, new ParsedRequestListener<User>() {
                     @Override
                     public void onResponse(User user) {
                        // do anything with response
                        Log.d(TAG, "id : " + user.id);
                        Log.d(TAG, "firstname : " + user.firstname);
                        Log.d(TAG, "lastname : " + user.lastname);
                     }
                     @Override
                     public void onError(ANError anError) {
                        // handle error
                     }
                 }); 
/*-- Note : YourObject.class, getAsObject and getAsObjectList are important here --*/              

Downloading a file from server

AndroidNetworking.download(url,dirPath,fileName)
                 .setTag("downloadTest")
                 .setPriority(Priority.MEDIUM)
                 .build()
                 .setDownloadProgressListener(new DownloadProgressListener() {
                    @Override
                    public void onProgress(long bytesDownloaded, long totalBytes) {
                      // do anything with progress  
                    }
                 })
                 .startDownload(new DownloadListener() {
                    @Override
                    public void onDownloadComplete() {
                      // do anything after completion
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error    
                    }
                });                 

Uploading a file to server

AndroidNetworking.upload(url)
                 .addMultipartFile("image",file)    
                 .addMultipartParameter("key","value")
                 .setTag("uploadTest")
                 .setPriority(Priority.HIGH)
                 .build()
                 .setUploadProgressListener(new UploadProgressListener() {
                    @Override
                    public void onProgress(long bytesUploaded, long totalBytes) {
                      // do anything with progress 
                    }
                 })
                 .getAsJSONObject(new JSONObjectRequestListener() {
                    @Override
                    public void onResponse(JSONObject response) {
                      // do anything with response                
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error 
                    }
                 }); 

Getting Response and completion in an another thread executor

(Note : Error and Progress will always be returned in main thread of application)

AndroidNetworking.upload(url)
                 .addMultipartFile("image",file)  
                 .addMultipartParameter("key","value")  
                 .setTag("uploadTest")
                 .setPriority(Priority.HIGH)
                 .build()
                 .setExecutor(Executors.newSingleThreadExecutor()) // setting an executor to get response or completion on that executor thread
                 .setUploadProgressListener(new UploadProgressListener() {
                    @Override
                    public void onProgress(long bytesUploaded, long totalBytes) {
                      // do anything with progress 
                    }
                 })
                 .getAsJSONObject(new JSONObjectRequestListener() {
                    @Override
                    public void onResponse(JSONObject response) {
                      // below code will be executed in the executor provided
                      // do anything with response                
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error 
                    }
                 }); 

Setting a Percentage Threshold For Not Cancelling the request if it has completed the given threshold

AndroidNetworking.download(url,dirPath,fileName)
                 .setTag("downloadTest")
                 .setPriority(Priority.MEDIUM)
                 .setPercentageThresholdForCancelling(50) // even if at the time of cancelling it will not cancel if 50% 
                 .build()                                 // downloading is done.But can be cancalled with forceCancel.
                 .setDownloadProgressListener(new DownloadProgressListener() {
                    @Override
                    public void onProgress(long bytesDownloaded, long totalBytes) {
                      // do anything with progress  
                    }
                 })
                 .startDownload(new DownloadListener() {
                    @Override
                    public void onDownloadComplete() {
                      // do anything after completion
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error    
                    }
                });   

Cancelling a request.

Any request with a given tag can be cancelled. Just do like this.

AndroidNetworking.cancel("tag"); // All the requests with the given tag will be cancelled.
AndroidNetworking.forceCancel("tag");  // All the requests with the given tag will be cancelled , even if any percent threshold is
                                       // set , it will be cancelled forcefully. 
AndroidNetworking.cancelAll(); // All the requests will be cancelled.  
AndroidNetworking.forceCancelAll(); // All the requests will be cancelled , even if any percent threshold is
                               // set , it will be cancelled forcefully.                           

Loading image from network into ImageView

      <com.androidnetworking.widget.ANImageView
          android:id="@+id/imageView"
          android:layout_width="100dp"
          android:layout_height="100dp"
          android:layout_gravity="center" />
          
      imageView.setDefaultImageResId(R.drawable.default);
      imageView.setErrorImageResId(R.drawable.error);
      imageView.setImageUrl(imageUrl);          

Getting Bitmap from url with some specified parameters

AndroidNetworking.get(imageUrl)
                 .setTag("imageRequestTag")
                 .setPriority(Priority.MEDIUM)
                 .setBitmapMaxHeight(100)
                 .setBitmapMaxWidth(100)
                 .setBitmapConfig(Bitmap.Config.ARGB_8888)
                 .build()
                 .getAsBitmap(new BitmapRequestListener() {
                    @Override
                    public void onResponse(Bitmap bitmap) {
                    // do anything with bitmap
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error
                    }
                });

Error Code Handling

public void onError(ANError error) {
   if (error.getErrorCode() != 0) {
        // received error from server
        // error.getErrorCode() - the error code from server
        // error.getErrorBody() - the error body from server
        // error.getErrorDetail() - just an error detail
        Log.d(TAG, "onError errorCode : " + error.getErrorCode());
        Log.d(TAG, "onError errorBody : " + error.getErrorBody());
        Log.d(TAG, "onError errorDetail : " + error.getErrorDetail());
        // get parsed error object (If ApiError is your class)
        ApiError apiError = error.getErrorAsObject(ApiError.class);
   } else {
        // error.getErrorDetail() : connectionError, parseError, requestCancelledError
        Log.d(TAG, "onError errorDetail : " + error.getErrorDetail());
   }
}

Remove Bitmap from cache or clear cache

AndroidNetworking.evictBitmap(key); // remove a bitmap with key from LruCache
AndroidNetworking.evictAllBitmap(); // clear LruCache

Prefetch a request (so that it can return from cache when required at instant)

AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllUsers/{pageNumber}")
                .addPathParameter("pageNumber", "0")
                .addQueryParameter("limit", "30")
                .setTag(this)
                .setPriority(Priority.LOW)
                .build()
                .prefetch();

Customizing OkHttpClient for a particular request

OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                .addInterceptor(new GzipRequestInterceptor())
                .build();
                
AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllUsers/{pageNumber}")
                 .addPathParameter("pageNumber", "0")
                 .addQueryParameter("limit", "3")
                 .addHeaders("token", "1234")
                 .setTag("test")
                 .setPriority(Priority.LOW)
                 .setOkHttpClient(okHttpClient) // passing a custom okHttpClient 
                 .build()
                 .getAsJSONArray(new JSONArrayRequestListener() {
                    @Override
                    public void onResponse(JSONArray response) {
                      // do anything with response
                    }
                    @Override
                    public void onError(ANError error) {
                    // handle error
                    }
                });

Making a conditional request (Building a request)

ANRequest.GetRequestBuilder getRequestBuilder = new ANRequest.GetRequestBuilder(ApiEndPoint.BASE_URL + ApiEndPoint.CHECK_FOR_HEADER);
               
if(isHeaderRequired){
 getRequestBuilder.addHeaders("token", "1234");
}

if(executorRequired){
 getRequestBuilder.setExecutor(Executors.newSingleThreadExecutor());
}
               
ANRequest anRequest = getRequestBuilder.build();       
                 
anRequest.getAsJSONObject(new JSONObjectRequestListener() {
    @Override
    public void onResponse(JSONObject response) {
      // do anything with response
    }
    @Override
    public void onError(ANError error) {
      // handle error
    }
});

ConnectionClass Listener to get current network quality and bandwidth

// Adding Listener
AndroidNetworking.setConnectionQualityChangeListener(new ConnectionQualityChangeListener() {
            @Override
            public void onChange(ConnectionQuality currentConnectionQuality, int currentBandwidth) {
              // do something on change in connectionQuality
            }
        });
        
// Removing Listener   
AndroidNetworking.removeConnectionQualityChangeListener();

// Getting current ConnectionQuality
ConnectionQuality connectionQuality = AndroidNetworking.getCurrentConnectionQuality();
if(connectionQuality == ConnectionQuality.EXCELLENT) {
  // do something
} else if (connectionQuality == ConnectionQuality.POOR) {
  // do something
} else if (connectionQuality == ConnectionQuality.UNKNOWN) {
  // do something
}
// Getting current bandwidth
int currentBandwidth = AndroidNetworking.getCurrentBandwidth(); // Note : if (currentBandwidth == 0) : means UNKNOWN

Getting Analytics of a request by setting AnalyticsListener on that

AndroidNetworking.download(url,dirPath,fileName)
                 .setTag("downloadTest")
                 .setPriority(Priority.MEDIUM)
                 .build()
                 .setAnalyticsListener(new AnalyticsListener() {
                      @Override
                      public void onReceived(long timeTakenInMillis, long bytesSent, long bytesReceived, boolean isFromCache) {
                          Log.d(TAG, " timeTakenInMillis : " + timeTakenInMillis);
                          Log.d(TAG, " bytesSent : " + bytesSent);
                          Log.d(TAG, " bytesReceived : " + bytesReceived);
                          Log.d(TAG, " isFromCache : " + isFromCache);
                      }
                  })
                 .setDownloadProgressListener(new DownloadProgressListener() {
                    @Override
                    public void onProgress(long bytesDownloaded, long totalBytes) {
                      // do anything with progress  
                    }
                 })
                 .startDownload(new DownloadListener() {
                    @Override
                    public void onDownloadComplete() {
                      // do anything after completion
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error    
                    }
                });  
Note : If bytesSent or bytesReceived is -1 , it means it is unknown                

Getting OkHttpResponse in Response

AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAnUserDetail/{userId}")
                .addPathParameter("userId", "1")
                .setTag(this)
                .setPriority(Priority.LOW)
                .setUserAgent("getAnUser")
                .build()
                .getAsOkHttpResponseAndParsed(new TypeToken<User>() {
                }, new OkHttpResponseAndParsedRequestListener<User>() {
                    @Override
                    public void onResponse(Response okHttpResponse, User user) {
                      // do anything with okHttpResponse and user
                    }
                    @Override
                    public void onError(ANError anError) {
                      // handle error
                    }
                });

Making Synchronous Request

ANRequest request = AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllUsers/{pageNumber}")
                        .addPathParameter("pageNumber", "0")
                        .addQueryParameter("limit", "3")
                        .build();
ANResponse<List<User>> response = request.executeForObjectList(User.class);
if (response.isSuccess()) {
   List<User> users = responseTwo.getResult();
} else {
   //handle error
}                                        

How caching works ?

  • First of all the server must send cache-control in header so that is starts working.
  • Response will be cached on the basis of cache-control max-age,max-stale.
  • If internet is connected and the age is NOT expired it will return from cache.
  • If internet is connected and the age is expired and if server returns 304(NOT MODIFIED) it will return from cache.
  • If internet is NOT connected if you are using getResponseOnlyIfCached() - it will return from cache even it date is expired.
  • If internet is NOT connected , if you are NOT using getResponseOnlyIfCached() - it will NOT return anything.
  • If you are using getResponseOnlyFromNetwork() , it will only return response after validation from server.
  • If cache-control is set, it will work according to the max-age,max-stale returned from server.
  • If internet is NOT connected only way to get cache Response is by using getResponseOnlyIfCached().

Enabling Logging

AndroidNetworking.enableLogging(); // simply enable logging
AndroidNetworking.enableLogging(LEVEL.HEADERS); // enabling logging with level

Enabling GZIP From Client to Server

// Enabling GZIP for Request (Not needed if your server doesn't support GZIP Compression), anyway responses 
// from server are automatically unGzipped if required. So enable it only if you need your request to be 
// Gzipped before sending to server(Make sure your server support GZIP Compression).
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                .addInterceptor(new GzipRequestInterceptor())
                .build();
AndroidNetworking.initialize(getApplicationContext(),okHttpClient);                

IMPORTANT NOTE

  • Use IMMEDIATE Priority with caution - use is at appropriate place only when 1 or 2 (at max 2)IMMEDIATE request is required at instant.Otherwise use HIGH Priority.

  • Known Bug : As present if you are using GZIP Interceptor from client to server, Upload progress is not working perfectly in Multipart.

    If you are using Proguard with Gradle build system (which is usually the case), you don't have to do anything. The appropriate Proguard rules will be automatically applied. If you still need the rules applied in proguard-rules.pro, it is as follows:

    -dontwarn okio.**
    

Fast Android Networking Library supports

  • Fast Android Networking Library supports all types of HTTP/HTTPS request like GET, POST, DELETE, HEAD, PUT, PATCH
  • Fast Android Networking Library supports downloading any type of file
  • Fast Android Networking Library supports uploading any type of file (supports multipart upload)
  • Fast Android Networking Library supports cancelling a request
  • Fast Android Networking Library supports setting priority to any request (LOW, MEDIUM, HIGH, IMMEDIATE)
  • Fast Android Networking Library supports RxJava

As it uses OkHttp as a networking layer, it supports:

  • Fast Android Networking Library supports HTTP/2 support allows all requests to the same host to share a socket
  • Fast Android Networking Library uses connection pooling which reduces request latency (if HTTP/2 isn’t available)
  • Transparent GZIP shrinks download sizes
  • Fast Android Networking Library supports response caching which avoids the network completely for repeat requests

Difference over other Networking Library

  • In Fast Android Networking Library, OkHttpClient can be customized for every request easily — like timeout customization, etc. for each request.
  • As Fast Android Networking Library uses OkHttp and Okio, it is faster.
  • Single library for all type of networking.
  • Supports RxJava, RxJava2 -> Check here
  • Current bandwidth and connection quality can be obtained to decide logic of code.
  • Executor can be passed to any request to get the response in another thread.
  • Complete analytics of any request can be obtained.
  • All types of customization are possible.
  • Immediate Request really is immediate now.
  • Prefetching of any request can be done so that it gives instant data when required from the cache.
  • Proper request canceling.
  • Prevents cancellation of a request if it’s completed more than a specific threshold percentage.
  • A simple interface to make any type of request.
  • Proper Response Caching — which leads to reduced bandwidth usage.

TODO

  • Integration with other library
  • And of course many many features and bug fixes

CREDITS

Contact - Let's become friend

License

   Copyright (C) 2024 Amit Shekhar

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

Contributing to Fast Android Networking

All pull requests are welcome, make sure to follow the contribution guidelines when you submit pull request.

fast-android-networking's People

Contributors

amitshekhariitbhu avatar anandgaurav10 avatar andreaboi83 avatar ayusch avatar brianon99 avatar dg76 avatar hi-manshu avatar johnwatsondev avatar modislaszlox2 avatar prashantgupta17 avatar rakshakhegde avatar supercilex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fast-android-networking's Issues

Add support for PersistentCookieJar

https://github.com/franmontiel/PersistentCookieJar

 @Override
    public void onCreate() {
        super.onCreate();
        // setup asynchronous client
               cookieJar =new PersistentCookieJar(new SetCookieCache(),
                          new SharedPrefsCookiePersistor(this.getApplicationContext()));

               okHttpClient = new OkHttpClient().newBuilder()
               .cookieJar(cookieJar)
               .build();

        AndroidNetworking.initialize(getApplicationContext(),okHttpClient);
        AndroidNetworking.setUserAgent(USER_AGENT);
        AndroidNetworking.enableLogging();

Separately instantiable (in case used by dependencies)

If this library gets popular then it can become a victim of its success.
If both an app and a dependent library use this library then their configurations and state could clash.

The current singleton approach is handy and may cover the vast majority of use cases, but many use cases may need to create dedicated instances that don't share config/state with other instances (ex: configuring GZIP might work against some servers used by the app, but not others used by a dependent library.

It looks like InternalNetworking, ANRequestQueue, and ANImageLoader would need to be refactored.

How to work with Sync calls ?

I am new to android development. Can you please help me here on How to deal with sync calls. I need to display data on UI only after receiving the data from server response. I can't do network calls on UI thread. So how can i prevent user interaction with UI while using Sync call using FAN.

onError method of DonwloadListener is not invoked when downloading error

My code is the same with the tutorial. But when I start downloading and something wrong with the priority, the downloading thread just stopped without any callback. I reviewed the code and found that methods in mDownloadListener and mUploadListener are not invoked in ANRequest.deliverErrorResponse(). Is it a bug?

why add header is no action

like this
public static void postStringJson(String url, HashMap<String,String> params,StringRequestListener listener){
AndroidNetworking.post(url).addHeaders(getRequestHeader()).addBodyParameter(params).build().getAsString(listener);
}

public static HashMap<String,String> getRequestHeader(){
    HashMap<String,String> headParams = new HashMap<>();
    headParams.put("Content-Type", "application/json");
    String token = SharedPreferenceUtil.getInstance(AppApplication.getInstance()).getString(SharedPreferenceUtil.TOKEN);
    if(!StringUtil.isEmpty(token)){
        headParams.put("Authorization","token "+token);
    }
    headParams.put("client","android");

    return headParams;
}

Stop.

stop commenting on ion issues with your stuff, unless it is relevant to the ion issue.

Don't work with header "application/x-www-form-urlencoded"

I need example post request with header "application/x-www-form-urlencoded". I tried this

             AndroidNetworking.post("url")
            .addUrlEncodeFormBodyParameter("grant_type","password")
            .addUrlEncodeFormBodyParameter("username",username)
            .addUrlEncodeFormBodyParameter("password",password)
            .addHeaders("Content-Type","application/x-www-form-urlencoded;charset=UTF8")
            .setTag("authentication")
            .setPriority(Priority.MEDIUM)
            .build()
            .getAsJSONObject(new JSONObjectRequestListener() {
                @Override
                public void onResponse(JSONObject response) {
                    Log.i("Data from api success", response.toString());
                }

                @Override
                public void onError(ANError anError) {
                    Log.i("Data from api error", anError.toString());
                }
            });

but it returns "Attempt to invoke virtual method 'okhttp3.HttpUrl$Builder okhttp3.HttpUrl.newBuilder()' on a null object reference"
Thank you

Support for custom respsonses, and response content type.

Hi,

Thanks again for wonderful library.

Please consider adding support to handle custom responses, and response Content-Type.

For example something like this for both post and get:

AndroidNetworking.get(pUrl)
.setPriority(Priority.LOW)
.build()
.getResponse(new ResponseListener() {
@OverRide
public void onResponse(Response response) {
// do anything with response
Logger.info(AsyncOkHttpTask.class, "AndroidNetworking.get - onResponse");

         String contentType = response.getContentType(); //application/json or application/text or xml etc...

         String body = response.getBodyAsString(); //getBodyAsBytes() or getBodyAsStream() etc....

         String status = response.getStatusString();

         int code = response.getResultCode();

     }

     @Override
     public void onError(ANError error) {
         // handle error
         Logger.info(AsyncOkHttpTask.class, "AndroidNetworking.get - onError");

     }

}

);

Kind Regards

Willem

Head request

I need example HEAD request. I tried this

AndroidNetworking.head (BASE_URL)
.addQueryParameter ("username", username)
.addQueryParameter ("password", password)
.setPriority (Priority.MEDIUM)
.build ()
.getAsString (stringRequestListener);

But the response is an empty string.

Question: Is there any option to define bandwidth for request?

i want to define the bandwidth of request during sending large file request with poor connectivity connection.
The priorty system doesnt help me in this case, because the request already in process.
it would be great if i could to tell for request to take X% of the bandwitdh.

TimeOut

How can I change the time out on a service request?

Something like:

AndroidNetworking.post(pUrl)
.addByteBody(bytes)
.setContentType("application/json")
.setPriority(Priority.HIGH)
.setExecutor(Executors.newSingleThreadExecutor())
.setTimeOut(60000) //milis
.build()
.getAsOkHttpResponse(new OkHttpResponseListener() {

Image download hangs UI

Image download working in main thread and it cause the hang of UI When showing the list of user with their profile images.
It must be like Glide or Picasso.

Let me know if I am wrong or I have to use any other/extra code for doing so.
Currently I am doing code as below....and showing in recyclerview using adapter.

public static void loadImageDirect(final String url, final ImageView img, final String TAG) {
        NetworkingBase.get(url)
                .setTag("imageRequestTag")
                .setPriority(Priority.MEDIUM)
                .setImageScaleType(null)
                .setBitmapMaxHeight(0)
                .setBitmapMaxWidth(0)
                .setBitmapConfig(Bitmap.Config.ARGB_8888)
                .build()
                .setAnalyticsListener(new AnalyticsListener() {
                    @Override
                    public void onReceived(long timeTakenInMillis, long bytesSent, long bytesReceived, boolean isFromCache) {
                        Log.d(TAG, " timeTakenInMillis : " + timeTakenInMillis);
                        Log.d(TAG, " bytesSent : " + bytesSent);
                        Log.d(TAG, " bytesReceived : " + bytesReceived);
                        Log.d(TAG, " isFromCache : " + isFromCache);
                    }
                })
                .getAsBitmap(new BitmapRequestListener() {
                    @Override
                    public void onResponse(final Bitmap response) {
                        Log.d(TAG, "onResponse Bitmap");
                                img.setImageBitmap(response);
                    }

                    @Override
                    public void onError(LibError error) {
                        if (error.getErrorCode() != 0) {

                            Log.d(TAG, "onError errorCode : " + error.getErrorCode());
                            Log.d(TAG, "onError errorBody : " + error.getErrorBody());
                            Log.d(TAG, "onError errorDetail : " + error.getErrorDetail());
                        } else {
                            // error.getErrorDetail() : connectionError, parseError, requestCancelledError
                            Log.d(TAG, "onError errorDetail : " + error.getErrorDetail());
                        }
                    }
                });
    }

and calling this loadImageDirect(...) method from adapter.

Android 6 Can not connect to server support SSLV3 and TLS 1.0 only

Hi I have a strange issue while using library to make post to Server which only support SSL v3 and TLS 1.0 only. Our request work fine with API level 22 and below. Only when use with android API 23 (android 6+) I have connection error

this my code to make POST request

String url2 = "https://prdesb1.singpost.com/ma/GetItemTrackingDetails";

final String payload2 = "<ItemTrackingDetailsRequest xmlns=\"http://singpost.com/paw/ns\"><ItemTrackingNumbers><TrackingNumber>SMT0000000628</TrackingNumber></ItemTrackingNumbers></ItemTrackingDetailsRequest>";

AndroidNetworking.initialize(this);
        AndroidNetworking.post(url2)
                .addHeaders("Content-Type","application/xml")
                .addByteBody(payload2.getBytes())
                .build()

                .getAsString(new StringRequestListener() {
                    @Override
                    public void onResponse(String response) {
                        Log.v("successAndroid1",response);
                    }

                    @Override
                    public void onError(ANError anError) {
                        Log.v("FailAndroidDetail",anError.getErrorDetail());
                        Log.v("FailAndroidBody",anError.getData().toString());


                        Log.v("FailAndroidCode",String.valueOf(anError.getErrorCode()));
                     }
                });

this only happen with android 6+. I have added all the necessary permission

cancelTag someTime is not taken into effect

public void cancelRequestWithGivenTag(final Object tag, final boolean forceCancel) {
        try {
            if (tag == null) {
                return;
            }
            cancel(new RequestFilter() {
                @Override
                public boolean apply(ANRequest request) {
                    return request.getTag() == tag;
                }
            }, forceCancel);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

if I used like this

public static void uploadFile(String url,String tag,HashMap<String, String> params, String key,File file, UploadProgressListener uploadProgressListener, StringRequestListener listener) {        

AndroidNetworking.upload(url)
.setTag(tag)
.addHeaders(getRequestHeader())
.addMultipartFile(key,file)
.addMultipartParameter(params)
.build()
.setUploadProgressListener(uploadProgressListener).getAsString(listener);
 }

 public static void cancleByTag(String tag){
        AndroidNetworking.cancel(tag);
  }

tag is no ==
I think if use equals will be better

isRedirect ?

Request URL:https://end_point/login
Request Method:POST
Status Code:302 Moved Temporarily
Remote Address:

OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.cookieJar(cookieJar)
.followRedirects(true)
.followSslRedirects(true)
.retryOnConnectionFailure(true)
.writeTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
.readTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
.connectTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
.build();

Api.login(username, password, new OkHttpResponseAndStringRequestListener() {
@OverRide
public void onResponse(Response okHttpResponse, String response) {

            if (okHttpResponse.isRedirect()){  // always status code=200 but not 302
                onLogged(0,0,false);
            }
            else
            {
                onError(errorMessage);
            }
        }

Retry Request

Is there a way to tell the request to retry on Authentication failure? My server uses token based authentication and I store the token in the Android Authentication System. When a request comes back from the server that says the token has expired I would like to be able to tell the authenticator to invalidate the cookie stored in the android system and then to retry the request. I have set up a custom okhttp client with an interceptor that automatically asks for authentication to be added to each request. Currently I am unsure how to tell it to retry the request.

BitmapFactory.Options and Utils.decodeBitmap()

Hi, you are doing a very nice job with your "hybrid" networking library!!! I was looking for a new networking lib for Android, with both the advantage of OkHttp and Volley (especially for the image part). However, as in the Volley lib, I can't set the BitmapFactory.Options flags that I need.

Is it possible to add a method like decodeBitmap but with the ability of pass a BitmapFactory.Options object instead of the Bitmap.Config? The best solution should be pass a "base" config to the main instance of the AndroidNetworking, so that the same config can be used for all bitmap decoding processes.

I really need this feature, because in some device I need to set on BitmapFactory.Options some other flags (like inPurgeable) for avoiding OOMs.

Please, help me :)! Thanks in advance.

Pass the OkHttpResponse object in onResponse method

Could you please provide support for, OkHttpResponse object will get passed as parameter in onResponse method of ParsedRequestListener interface?
In that case, we can get the status code/headers from OkHttpResponse object and still enjoying the parsed object in onResponse.

For better visualization, my request can be summarized below,

.getAsParsed(new TypeToken<User>() {}, new ParsedRequestListener<User>() {
    @Override
    public void onResponse(Response response, User user) {
        // we can find header like response.headers()
        // we can get user as parsed
    }

    @Override
    public void onError(ANError anError) {
        // handle error
    }
}); 

Thanks in advance!

P.S: Requested the same feature as a comment in another issue. The issue has been closed. So I am creating a separate issue.

Question: Can library support optional query parameters?

So, I want call to google place autocomplete api, exists "language" query parameter in api and this parameter is optional, may be will be value or not. And my question do support library optional query parameter, library will be skip if I call AndroidNetworking library like as :

AndroidNetworking.get("https://maps.googleapis.com/maps/api/place/autocomplete/json")
     .addQueryParameter("input", "Berlin")
     .addQueryParameter("language", null)
     .setExecutor(Executors.newSingleThreadExecutor())
    .setTag("placeReq")
    .build()
    .getAsJSONObject(new JSONObjectRequestListener() {
        @Override
        public void onResponse(JSONObject response) {}
        @Override
        public void onError(ANError anError) {}
    });

?
Thank you for advance!

Timeouts never ocurr

I have tried using this code:
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().connectTimeout(1, TimeUnit.SECONDS).readTimeout(1, TimeUnit.SECONDS).writeTimeout(1, TimeUnit.SECONDS).build(); ANRequest request = AndroidNetworking.get(url).setOkHttpClient(okHttpClient).build(); ANResponse<String> response = request.executeForString();

and

OkHttpClient okHttpClient = new OkHttpClient().newBuilder().connectTimeout(1, TimeUnit.SECONDS).readTimeout(1, TimeUnit.SECONDS).writeTimeout(1, TimeUnit.SECONDS).build(); AndroidNetworking.initialize(getApplicationContext(), okHttpClient);

And both never timeout (and neither do they respond).

Set default event for all request

Can i set default function call back when get result from the server? In my case, if error code = 401 i want to change specific activity (I want write 1 time for all request, not write many times on all request).

Android Networking library

hi,
thanks for your library.
I have a question about posting data:
when i send persion character to server with your library.in server the charaters are not same.
for example i send "ولی" to server. in server it show "#as$*^".
how can i send UTF-8 ?

bad encoding

(Example)
I'm get this xml(I not control he) with "getAsString":

<?xml version="1.0" encoding="iso-8859-1" ?>
        <test>
            <text name="Café" />
       </test>

but he not return the correct result:

<?xml version="1.0" encoding="iso-8859-1" ?>
        <test>
            <text name="Caf�" />
       </test>

Strange problem

I have a strange problem. I use a simple HTTP POST form for authentication, use two accounts with different user credentials (username and passowrd). Often, to sign up with one account and http data are from other. I tried it with Android Asynchronous HTTP Client (http://loopj.com/android-async-http) and the problem did not show up ... I do not understand how this is possible

Asynchronous task

Whenever we implement Volley , there is no need to use AsyncTask or IntentService for long time operations to avoid ANR.

in Fast-Android-Networking , should I use asyncTask ?

thanks

Server shows empty body when using POST addJSONObjectBody

Symptoms: When POSTing a valid JSONObject (89 characters deserialized) to an Ubuntu Apache Slim PHP (http://www.slimframework.com, https://github.com/slimphp/Slim) server, both Stetho and AnalyticsListener say that 89 bytes was sent, but the server sees only an empty/null body.
When I make what I believe to be the exact same request using Volley the server responds just fine as expected.
(I have yet to get Stetho to work w/ Volley, so I cannot confirm how identical the request is or isn't)

I believe that my code is pretty straightforward:

public String requestJSONObject(
        final String tag,
        @NonNull
        Uri uri,
        HashMap<String, String> bodyParameterMap)
{
    JSONObject jsonObjectBody;
    if (bodyParameterMap == null)
    {
        jsonObjectBody = null;
    }
    else
    {
        jsonObjectBody = new JSONObject();
        for (Entry<String, String> entry : bodyParameterMap.entrySet())
        {
            String key = entry.getKey();
            String value = entry.getValue();
            try
            {
                jsonObjectBody.put(key, value);
            }
            catch (JSONException e)
            {
                // ignore
            }
        }
    }

    ANRequest request = AndroidNetworking.post(uri.toString())
            .setTag(tag)
            .addHeaders("User-Agent", mUserAgent)
            .addHeaders("APP-ID", mAppId)
            .addHeaders("Debug", "true")
            .addJSONObjectBody(jsonObjectBody)
            .build();

    request.setAnalyticsListener(new AnalyticsListener()
    {
        @Override
        public void onReceived(long timeTakenInMillis, long bytesSent, long bytesReceived, boolean isFromCache)
        {
            Log.e(TAG, " timeTakenInMillis : " + timeTakenInMillis);
            Log.e(TAG, " bytesSent : " + bytesSent);
            Log.e(TAG, " bytesReceived : " + bytesReceived);
            Log.e(TAG, " isFromCache : " + isFromCache);
        }
    });

    request.getAsOkHttpResponseAndJSONObject(new OkHttpResponseAndJSONObjectRequestListener()
    {
        @Override
        public void onResponse(Response okHttpResponse, JSONObject response)
        {
            Log.i(TAG, "requestJSONObject(tag=" + tag + ") onResponse: response=" + response);
            //...
        }

        @Override
        public void onError(ANError anError)
        {
            Log.w(TAG, "requestJSONObject(tag=" + tag + ") onError: anError=" + Utils.toString(anError));
            //...
        }
    });

    return tag;
}

Usage:

Uri uri = Uri.parse("http://api.redacted.com")
    .buildUpon()
    .appendPath("oauth2")
    .appendPath("token")
    .build();
HashMap<String, String> postBodyParameters = new HashMap<>();
postBodyParameters.put("grant_type", "refresh_token");
postBodyParameters.put("refresh_token", refreshToken);
requestJSONObject("mytag", uri, postBodyParameters);

Stetho sniff:

Request URL:http://api.redacted.com/oauth2/token
Request Method:POST
Status Code:400 Bad Request
Request Headers:
Accept-Encoding:gzip
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:95
Content-Type:application/json; charset=utf-8
Host:api.redacted.com
APP-ID:redacted
User-Agent:Dalvik/2.1.0 (Linux; U; Android 5.1.1; Nexus 5 Build/LMY48B); com.redacted.testapp 1.0
Request Payload:
{"refresh_token":"redacted","grant_type":"refresh_token"}
Response Headers:
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:close
Content-Length:101
Content-Type:application/json; charset=utf-8
Date:Tue, 08 Nov 2016 22:34:26 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
OkHttp-Received-Millis:1478644376230
OkHttp-Sent-Millis:1478644375903
Pragma:no-cache
Server:Apache/2.4.7 (Ubuntu)
Set-Cookie:PHPSESSID=au8iauf08b2i3qnu4nbrd40ts6; path=/
X-Powered-By:PHP/5.5.9-1ubuntu4.20
Response Payload:
{"error":[{"message":"Post body is empty.","transaction_id":"redacted"}]}{"post_body":null}

(I had my web developer output to the response the post body that he read.)

Any idea why AN doesn't work, but Volley does?

Rx integration

Are you guys planning to implement rxjava integration

Please remove android:allowBackup attribute in <application> tag

When I built project with rx-android-networking library I got the error message below:

    Attribute application@allowBackup value=(false) from AndroidManifest.xml:65:7-34
    is also present at [com.amitshekhar.android:rx-android-networking:0.1.0] AndroidManifest.xml:28:9-35 value=(true).
    Suggestion: add 'tools:replace="android:allowBackup"' to <application> element at AndroidManifest.xml:63:3-663:17 to override.

Thanks for hard working.

Invalidate url from cache after I get response ?

Well I found workaround but kind of ugly...

public static void invalidate(String url) {
        try {
            Iterator<String> it = _client.cache().urls();
            while (it.hasNext()) {
                String next = it.next();
                if (next.contains(url)) it.remove();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

How to set timeout in Request

ErrorCode=0,
ErrorMessage=com.androidnetworking.error.ANError: java.net.SocketTimeoutException

How I solve this problem, please?

Add support for custom content-type

Thanks for great library.

Please add support to add custom content-type when using RequestBuilder. It would be nice to be able to add bytes as the body, then custom content-type.

Something like:

AndroidNetworking.post(url).addByteBody(bytes).addContentType("application/json")

Regards,

Willem

Enhancement the log system

There were some logs by setting AndroidNetworking.enableLogging(); through a upload file request.

D/AndroidNetworking: addRequest: after addition - mCurrentRequests size: 1

D/AndroidNetworking: execution started : ANRequest{sequenceNumber='1, mMethod=1, mPriority=HIGH, mRequestType=2, mUrl=someUrl}

D/AndroidNetworking: Delivering success : ANRequest{sequenceNumber='1, mMethod=1, mPriority=HIGH, mRequestType=2, mUrl=someUrl}

D/AndroidNetworking: execution done : ANRequest{sequenceNumber='1, mMethod=1, mPriority=HIGH, mRequestType=2, mUrl=someUrl}

D/AndroidNetworking: finish: after removal - mCurrentRequests size: 0

Should it show some HTTP header and body just like okhttp logging system?

Maybe did I just replace the default OkHttpClient with custom OkHttpClient which enable its' logging function? (P.S. I'm a lazy guy. :))

Thanks in advance.

Gif Image support

it seems powerful library,can make it load gif image from network?

Get cookies from response ?

Is this possible ? I want to pass them to webkit cookie manager so I get logged in web browser too.... I am trying to replace Android Query with this library but it is not that easy.

Incomplete URLs

Is it possible to set only the path of the url but not the host. I would like to have the request be something like AndroidNetworking.get("/the/coolest/endpoint/ever")...
Then in the interceptor I will append the server to the front of the request before sending it.
public Response intercept(Chain chain) throws IOException { Request request = chain.request(); request = request.newBuilder() .url("https://myServer"+request.url().toString()) .addHeader("cookie", getAuthentication(context)) .build(); Response response = chain.proceed(request);

Currently when I do this the onError method gets fired with the following.
java.lang.NullPointerException: Attempt to invoke virtual method 'okhttp3.HttpUrl$Builder okhttp3.HttpUrl.newBuilder()' on a null object reference

Also it never gets to the interceptor to inject the first part of the url

cant get Headers

Headers s=AndroidNetworking.get("http://www.frendz4m.com/forum/login.php")
.build().getHeaders() ;
textView.setText(s.toMultimap().values().size()+"");

final ANRequest s=AndroidNetworking.post("http://www.frendz4m.com/forum/authenticate.php")
.addHeaders("Cookie",cookieToString(cookies))
.build() ;
String str=s.getHeaders().get("Set-Cookie")+"";

addHeaders() method working fine.

but getHeaders() return null value

I want to save cookies. but i am unable to get "Set-Cookie:" header

Question: How to get response in worker thread?

Hi, thanks you for great library! I've a question, I need get response in worker thread and doing somethings(parsing, saving, sorting) and after completing all operation then showing result in main thread. Can you say how to solve this problem with Fast-Android-Networking without sync request. Because I don't want open extra custom thread and send request with synchronous and doing all operation and then pass result main thread. I'm currently doing with this still, but some code boilerplate. I want use asynchronous request of "Fast-Android-Networking" but get response on worker background thread. It is possible?

spam

please stop spamming the blogs with links to your project. one post per blog is sufficient, you don't have to do more than that. it's obnoxious and it makes you look unprofessional

enhancement for android old versions : Network Bandwidth Quality

when a network request finished you took the Content-Length and the TimeMS of the request for calculating the quality of the network but there is an additional parameter that you should take care of when you calculating the bandwidth quality: How much requests you perform in parallel during the request because the bandwidth divided for all your request in the app

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.