Android Open Source - fh-android-sdk F H Sync Client






From Project

Back to project page fh-android-sdk.

License

The source code is released under:

Copyright (c) 2014 FeedHenry Ltd, All Rights Reserved. Please refer to your contract with FeedHenry for the software license agreement. If you do not have a contract, you do not have a license to use...

If you think the Android project fh-android-sdk listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.feedhenry.sdk.sync;
/*from   w ww  .  ja va  2s .  c  o m*/
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.json.fh.JSONObject;

import android.content.Context;
import android.os.HandlerThread;
import android.os.Looper;
import android.util.Log;

import com.feedhenry.sdk.FH;
import com.feedhenry.sdk.FHActCallback;
import com.feedhenry.sdk.api.FHActRequest;
import com.feedhenry.sdk.exceptions.FHNotReadyException;
import com.feedhenry.sdk.utils.FHLog;

/**
 * The sync client is part of the FeedHenry data sync framework. It provides a mechanism to manage bi-direction data synchronization.
 * For more details, please check <a href="http://docs.feedhenry.com/v2/development_sync_service.html">data sync framewrok docs</a>.
 */
public class FHSyncClient {
  
  private static FHSyncClient mInstance;
  
  protected static final String LOG_TAG = "com.feedhenry.sdk.sync.FHSyncClient";
  
  private Context mContext;
  private Map<String, FHSyncDataset> mDataSets = new HashMap<String, FHSyncDataset>();
  private FHSyncConfig mConfig = new FHSyncConfig();
  private FHSyncListener mSyncListener = null;
  
  private FHSyncNotificationHandler mNotificationHandler;
  
  private boolean mInitialised = false;
  private MonitorTask mMonitorTask = null;
  
  private ExecutorService mExecutors = Executors.newFixedThreadPool(3);
  
  /**
   * Get the singleton instance of the sync client.
   * @return the sync client instance
   */
  public static FHSyncClient getInstance(){
    if(null == mInstance){
      mInstance = new FHSyncClient();
    }
    return mInstance;
  }
  
  /**
   * Initialize the sync client. Should be called every time an app/activity starts.
   * @param pContext The app context
   * @param pConfig The sync configuration
   * @param pListener The sync listener
   */
 
  public void init(Context pContext, FHSyncConfig pConfig, FHSyncListener pListener){
    mContext = pContext;
    mConfig = pConfig;
    mSyncListener = pListener;
    initHanlders();
    mInitialised = true;
    if(null == mMonitorTask){
      mMonitorTask = new MonitorTask();
      mMonitorTask.start();
    }
  }
  
  /**
   * Initialize the notification handlers
   */
  private void initHanlders(){
    if(null != Looper.myLooper()){
      mNotificationHandler = new FHSyncNotificationHandler(this.mSyncListener);
    } else {
      HandlerThread ht = new HandlerThread("FHSyncClientNotificationHanlder");
      mNotificationHandler = new FHSyncNotificationHandler(ht.getLooper(), this.mSyncListener);
      ht.start();
    }
  }
  
  /**
   * Re-set the sync listener
   * @param pListener the new sync listener
   */
  public void setListener(FHSyncListener pListener){
    mSyncListener = pListener;
    if(null != mNotificationHandler){
      mNotificationHandler.setSyncListener(mSyncListener);
    }
  }
  
  /**
   * Use the sync client to manage a dataset.
   * @param pDataId The id of the dataset.
   * @param pConfig The sync configuration for the dataset. If not specified, the sync configuration passed in the init method will be used 
   * @param pQueryParams Query parameters for the dataset
   * @throws Exception
   */
  public void manage(String pDataId, FHSyncConfig pConfig, JSONObject pQueryParams) throws Exception {
    if(!mInitialised){
      throw new Exception("FHSyncClient isn't initialised. Have you called the init function?");
    }
    FHSyncDataset dataset = mDataSets.get(pDataId);
    FHSyncConfig syncConfig = mConfig;
    if(null != pConfig){
      syncConfig = pConfig;
    }
    if(null != dataset){
      dataset.setContext(mContext);
      dataset.setNotificationHandler(mNotificationHandler);
    } else {
      dataset = new FHSyncDataset(mContext, mNotificationHandler, pDataId, syncConfig, pQueryParams);
      mDataSets.put(pDataId, dataset);
      dataset.setSyncRunning(false);
      dataset.setInitialised(true);
    }
    
    dataset.setSyncConfig(syncConfig);
    dataset.setSyncPending(true);
    
    dataset.writeToFile();
  }
  
  /**
   * List all the data in the dataset with pDataId. 
   * @param pDataId The id of the dataset
   * @return all data records. Each record contains a key "uid" with the id value and a key "data" with the JSON data.
   */
  public JSONObject list(String pDataId) {
    FHSyncDataset dataset = mDataSets.get(pDataId);
    JSONObject data = null;
    if(null != dataset){
      data = dataset.listData();
    }
    return data;
  }
  
  /**
   * Read a data record with pUID in dataset with pDataId
   * @param pDataId the id of the dataset
   * @param pUID the id of the data record
   * @return the data record. Each record contains a key "uid" with the id value and a key "data" with the JSON data.
   */
  public JSONObject read(String pDataId, String pUID) {
    FHSyncDataset dataset = mDataSets.get(pDataId);
    JSONObject data = null;
    if(null != dataset){
      data = dataset.readData(pUID);
    }
    return data;
  }
  
  /**
   * Create a new data record in dataset with pDataId
   * @param pDataId the id of the dataset
   * @param pData the actual data
   * @return the created data record. Each record contains a key "uid" with the id value and a key "data" with the JSON data.
   * @throws Exception
   */
  public JSONObject create(String pDataId, JSONObject pData) throws Exception {
    FHSyncDataset dataset = mDataSets.get(pDataId);
    if(null != dataset){
      return dataset.createData(pData);
    } else {
      throw new Exception("Unkonw dataId : " + pDataId);
    }
  }
  
  /**
   * Update an existing data record in dataset with pDataId
   * @param pDataId the id of the dataset
   * @param pUID the id of the data record
   * @param pData the new content of the data record
   * @return the updated data record. Each record contains a key "uid" with the id value and a key "data" with the JSON data.
   * @throws Exception
   */
  public JSONObject update(String pDataId, String pUID, JSONObject pData) throws Exception {
    FHSyncDataset dataset = mDataSets.get(pDataId);
    if(null != dataset){
      return dataset.updateData(pUID, pData);
    } else {
      throw new Exception("Unkonw dataId : " + pDataId);
    }
  }
  
  /**
   * Delete a data record in the dataset with pDataId
   * @param pDataId the id of the dataset
   * @param pUID the id of the data record
   * @return the deleted data record. Each record contains a key "uid" with the id value and a key "data" with the JSON data.
   * @throws Exception
   */
  public JSONObject delete(String pDataId, String pUID) throws Exception {
    FHSyncDataset dataset = mDataSets.get(pDataId);
    if(null != dataset){
      return dataset.deleteData(pUID);
    } else {
      throw new Exception("Unkonw dataId : " + pDataId);
    }
    
  }
  
  /**
   * List sync collisions in dataset with id pDataId
   * @param pDataId the id of the dataset
   * @param pCallback the callback function
   * @throws Exception
   */
  public void listCollisions(String pDataId, FHActCallback pCallback) throws Exception {
    JSONObject params = new JSONObject();
    params.put("fn", "listCollisions");
    FHActRequest request = FH.buildActRequest(pDataId, params);
    request.executeAsync(pCallback);
  }
  
  /**
   * Remove a sync collision record in the dataset with id pDataId
   * @param pDataId the id of the dataset
   * @param pCollisionHash the hash value of the collision record
   * @param pCallback the callback function
   * @throws Exception
   */
  public void removeCollision(String pDataId, String pCollisionHash, FHActCallback pCallback) throws Exception {
    JSONObject params = new JSONObject();
    params.put("fn", "removeCollision");
    params.put("hash", pCollisionHash);
    FHActRequest request = FH.buildActRequest(pDataId, params);
    request.executeAsync(pCallback);
  }
  
  /**
   * Stop the sync process for dataset with id pDataId
   * @param pDataId the id of the dataset
   * @throws Exception
   */
  public void stop(String pDataId) throws Exception {
    FHSyncDataset dataset = mDataSets.get(pDataId);
    if(null != dataset){
      dataset.stopSync(true);
    }
  }
  
  /**
   * Stop all sync processes for all the datasets managed by the sync client.
   * @throws Exception
   */
  public void destroy() throws Exception {
    if(mInitialised){
      if(null != mMonitorTask){
        mMonitorTask.stopRunning();
        mMonitorTask.stop();
      }
      for(String key: mDataSets.keySet()){
        stop(key);
      }
      mSyncListener = null;
      mNotificationHandler = null;
      mDataSets = null;
      mInitialised = false;
    }
  }
  
  private class MonitorTask extends Thread{

    private boolean mKeepRunning = true;
    
    public void stopRunning(){
      mKeepRunning = false;
    }
    
    private void checkDatasets(){
      if(null != mDataSets){
        for(Map.Entry<String, FHSyncDataset> entry: mDataSets.entrySet()){
          final FHSyncDataset dataset = entry.getValue();
          boolean syncRunning = dataset.isSyncRunning();
          if(!syncRunning && !dataset.isStopSync()){
            //sync isn't running for dataId at the moment, check if needs to start it
            Date lastSyncStart = dataset.getSyncStart();
            Date lastSyncEnd = dataset.getSyncEnd();
            if(null == lastSyncStart){
              dataset.setSyncPending(true);
            } else if(null != lastSyncEnd){
              long interval = new Date().getTime() - lastSyncEnd.getTime();
              if(interval > dataset.getSyncConfig().getSyncFrequency()*1000){
                Log.d(LOG_TAG, "Should start sync!!");
                dataset.setSyncPending(true);
              }
            }
            
            if(dataset.isSyncPending()){
              mExecutors.submit(new Runnable() {
                @Override
                public void run() {
                  dataset.startSyncLoop();
                }
              });
            }
          }
        }
      }
    }
    
    @Override
    public void run() {
      while(mKeepRunning && !isInterrupted()){
        checkDatasets();
        try{
          Thread.sleep(1000);
        }catch(Exception e){
          FHLog.e(LOG_TAG, "MonitorTask thread is interrupted", e);
          this.interrupt();
        }
        
      }
    }
    
  }
}




Java Source Code List

com.feedhenry.fhandroidexampleapp.FHActActivity.java
com.feedhenry.fhandroidexampleapp.FHAndroidExampleActivity.java
com.feedhenry.fhandroidexampleapp.FHAuthActivity.java
com.feedhenry.fhandroidexampleapp.FHLoginActivity.java
com.feedhenry.fhandroidexampleapp.FHSyncActivity.java
com.feedhenry.fhandroidexampleapp.FhUtil.java
com.feedhenry.fhandroidexampleapp.ItemDetailsActivity.java
com.feedhenry.fhandroidexampleapp.SyncCollisionResolveActivity.java
com.feedhenry.fhandroidexampleapp.SyncCollisionsListActivity.java
com.feedhenry.sdk.CloudProps.java
com.feedhenry.sdk.FHActCallback.java
com.feedhenry.sdk.FHAct.java
com.feedhenry.sdk.FHHttpClient.java
com.feedhenry.sdk.FHRemote.java
com.feedhenry.sdk.FHResponse.java
com.feedhenry.sdk.FH.java
com.feedhenry.sdk.api.FHActRequest.java
com.feedhenry.sdk.api.FHAuthRequest.java
com.feedhenry.sdk.api.FHCloudRequest.java
com.feedhenry.sdk.api.FHInitializeRequest.java
com.feedhenry.sdk.exceptions.FHInvalidActionException.java
com.feedhenry.sdk.exceptions.FHNotReadyException.java
com.feedhenry.sdk.oauth.FHOAuthIntent.java
com.feedhenry.sdk.oauth.FHOAuthWebView.java
com.feedhenry.sdk.sync.FHSyncClient.java
com.feedhenry.sdk.sync.FHSyncConfig.java
com.feedhenry.sdk.sync.FHSyncDataRecord.java
com.feedhenry.sdk.sync.FHSyncDataset.java
com.feedhenry.sdk.sync.FHSyncListener.java
com.feedhenry.sdk.sync.FHSyncNotificationHandler.java
com.feedhenry.sdk.sync.FHSyncPendingRecord.java
com.feedhenry.sdk.sync.FHSyncUtils.java
com.feedhenry.sdk.sync.NotificationMessage.java
com.feedhenry.sdk.utils.FHLog.java
com.feedhenry.starter.FHStarterActivity.java
com.loopj.android.http.AsyncHttpClient.java
com.loopj.android.http.AsyncHttpRequest.java
com.loopj.android.http.AsyncHttpResponseHandler.java
com.loopj.android.http.Base64DataException.java
com.loopj.android.http.Base64OutputStream.java
com.loopj.android.http.Base64.java
com.loopj.android.http.BaseJsonHttpResponseHandler.java
com.loopj.android.http.BinaryHttpResponseHandler.java
com.loopj.android.http.DataAsyncHttpResponseHandler.java
com.loopj.android.http.FileAsyncHttpResponseHandler.java
com.loopj.android.http.JsonHttpResponseHandler.java
com.loopj.android.http.JsonStreamerEntity.java
com.loopj.android.http.MyRedirectHandler.java
com.loopj.android.http.MySSLSocketFactory.java
com.loopj.android.http.PersistentCookieStore.java
com.loopj.android.http.PreemtiveAuthorizationHttpRequestInterceptor.java
com.loopj.android.http.RangeFileAsyncHttpResponseHandler.java
com.loopj.android.http.RequestHandle.java
com.loopj.android.http.RequestParams.java
com.loopj.android.http.ResponseHandlerInterface.java
com.loopj.android.http.RetryHandler.java
com.loopj.android.http.SerializableCookie.java
com.loopj.android.http.SimpleMultipartEntity.java
com.loopj.android.http.SyncHttpClient.java
com.loopj.android.http.TextHttpResponseHandler.java
org.json.fh.CDL.java
org.json.fh.CookieList.java
org.json.fh.Cookie.java
org.json.fh.HTTPTokener.java
org.json.fh.HTTP.java
org.json.fh.JSONArray.java
org.json.fh.JSONException.java
org.json.fh.JSONObject.java
org.json.fh.JSONString.java
org.json.fh.JSONStringer.java
org.json.fh.JSONTokener.java
org.json.fh.JSONWriter.java
org.json.fh.XMLTokener.java
org.json.fh.XML.java