- Moved the NetworkService management logic to the newly introduced NetworkServiceManager class
This commit is contained in:
parent
94986a4786
commit
593d3fc0d8
9 changed files with 151 additions and 83 deletions
|
@ -10,7 +10,7 @@ android {
|
|||
buildToolsVersion "25.0.0"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 9
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 24
|
||||
versionCode 12
|
||||
versionName "0.4.7-alpha3"
|
||||
|
|
|
@ -99,8 +99,12 @@ public class NetworkService extends Service {
|
|||
return mCurrentId;
|
||||
}
|
||||
|
||||
public int sendMessage(ApiCallable apiCallable){
|
||||
ApiCall call = apiCallable.toApiCall(mApiIds.get(ApiAccess.API_DATABASE), mCurrentId);
|
||||
public int sendMessage(ApiCallable apiCallable, int requiredApi){
|
||||
int apiId = 0;
|
||||
if(requiredApi != -1){
|
||||
apiId = mApiIds.get(requiredApi);
|
||||
}
|
||||
ApiCall call = apiCallable.toApiCall(apiId, mCurrentId);
|
||||
if(mWebSocket.send(call.toJsonString())){
|
||||
Log.v(TAG,"> "+call.toJsonString());
|
||||
}else{
|
||||
|
@ -112,7 +116,8 @@ public class NetworkService extends Service {
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
Log.d(TAG,"onDestroy");
|
||||
mWebSocket.close(NORMAL_CLOSURE_STATUS, null);
|
||||
if(mWebSocket != null)
|
||||
mWebSocket.close(NORMAL_CLOSURE_STATUS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
package cy.agorise.graphenej.api.android;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* This class should be instantiated at the application level of the android app.
|
||||
*
|
||||
* It will monitor the interaction between the different activities of an app and help us decide
|
||||
* when the connection to the full node should be interrupted.
|
||||
*/
|
||||
|
||||
public class NetworkServiceManager implements Application.ActivityLifecycleCallbacks {
|
||||
private final String TAG = this.getClass().getName();
|
||||
|
||||
/**
|
||||
* Constant used to specify how long will the app wait for another activity to go through its starting life
|
||||
* cycle events before running the teardownConnectionTask task.
|
||||
*
|
||||
* This is used as a means to detect whether or not the user has left the app.
|
||||
*/
|
||||
private final int DISCONNECT_DELAY = 1500;
|
||||
|
||||
/**
|
||||
* Handler instance used to schedule tasks back to the main thread
|
||||
*/
|
||||
private Handler mHandler = new Handler();
|
||||
|
||||
/**
|
||||
* Weak reference to the application context
|
||||
*/
|
||||
private WeakReference<Context> mContextReference;
|
||||
|
||||
// In case we want to interact directly with the service
|
||||
private NetworkService mService;
|
||||
|
||||
/**
|
||||
* Runnable used to schedule a service disconnection once the app is not visible to the user for
|
||||
* more than DISCONNECT_DELAY milliseconds.
|
||||
*/
|
||||
private final Runnable mDisconnectRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Context context = mContextReference.get();
|
||||
if(mService != null){
|
||||
context.unbindService(mServiceConnection);
|
||||
mService = null;
|
||||
}
|
||||
context.stopService(new Intent(context, NetworkService.class));
|
||||
}
|
||||
};
|
||||
|
||||
public NetworkServiceManager(Context context){
|
||||
mContextReference = new WeakReference<Context>(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Activity activity, Bundle bundle) {
|
||||
if(mService == null){
|
||||
// Starting a NetworkService instance
|
||||
Context context = mContextReference.get();
|
||||
Intent intent = new Intent(context, NetworkService.class);
|
||||
context.startService(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(Activity activity) {
|
||||
mHandler.removeCallbacks(mDisconnectRunnable);
|
||||
if(mService == null){
|
||||
Context context = mContextReference.get();
|
||||
Intent intent = new Intent(context, NetworkService.class);
|
||||
context.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(Activity activity) {
|
||||
mHandler.postDelayed(mDisconnectRunnable, DISCONNECT_DELAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(Activity activity) {}
|
||||
|
||||
@Override
|
||||
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {}
|
||||
|
||||
/** Defines callbacks for backend binding, passed to bindService() */
|
||||
private ServiceConnection mServiceConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className,
|
||||
IBinder service) {
|
||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
||||
NetworkService.LocalBinder binder = (NetworkService.LocalBinder) service;
|
||||
mService = binder.getService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName componentName) {}
|
||||
};
|
||||
}
|
|
@ -6,7 +6,6 @@ package cy.agorise.graphenej.api.bitshares;
|
|||
|
||||
public class Nodes {
|
||||
public static final String[] NODE_URLS = {
|
||||
"wss://bitshares.nus/ws",
|
||||
"wss://dexnode.net/ws", // Dallas, USA
|
||||
"wss://bitshares.crypto.fans/ws", // Munich, Germany
|
||||
"wss://bitshares.openledger.info/ws", // Openledger node
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.io.Serializable;
|
|||
import java.util.ArrayList;
|
||||
|
||||
import cy.agorise.graphenej.RPC;
|
||||
import cy.agorise.graphenej.api.ApiAccess;
|
||||
import cy.agorise.graphenej.models.ApiCall;
|
||||
|
||||
/**
|
||||
|
@ -12,6 +13,8 @@ import cy.agorise.graphenej.models.ApiCall;
|
|||
|
||||
public class GetBlock implements ApiCallable {
|
||||
|
||||
public static final int REQUIRED_API = ApiAccess.API_DATABASE;
|
||||
|
||||
private long blockNumber;
|
||||
|
||||
public GetBlock(int blockNum){
|
||||
|
|
|
@ -9,6 +9,7 @@ import cy.agorise.graphenej.BaseOperation;
|
|||
import cy.agorise.graphenej.BlockData;
|
||||
import cy.agorise.graphenej.RPC;
|
||||
import cy.agorise.graphenej.Transaction;
|
||||
import cy.agorise.graphenej.api.ApiAccess;
|
||||
import cy.agorise.graphenej.models.ApiCall;
|
||||
|
||||
/**
|
||||
|
@ -17,6 +18,8 @@ import cy.agorise.graphenej.models.ApiCall;
|
|||
|
||||
public class GetRequiredFees implements ApiCallable {
|
||||
|
||||
public static final int REQUIRED_API = ApiAccess.API_DATABASE;
|
||||
|
||||
private Transaction mTransaction;
|
||||
private Asset mFeeAsset;
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
@OnClick(R.id.send_message)
|
||||
public void onSendMesage(View v){
|
||||
GetBlock getBlock = new GetBlock(1000000);
|
||||
mService.sendMessage(getBlock);
|
||||
mService.sendMessage(getBlock, GetBlock.REQUIRED_API);
|
||||
}
|
||||
|
||||
@OnClick(R.id.next_activity)
|
||||
|
@ -93,8 +93,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
super.onStart();
|
||||
// Bind to LocalService
|
||||
Intent intent = new Intent(this, NetworkService.class);
|
||||
int requestedApis = ApiAccess.API_DATABASE | ApiAccess.API_HISTORY | ApiAccess.API_NETWORK_BROADCAST;
|
||||
intent.putExtra(NetworkService.KEY_REQUESTED_APIS, requestedApis);
|
||||
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,91 +1,24 @@
|
|||
package com.luminiasoft.labs.sample;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import cy.agorise.graphenej.api.android.NetworkService;
|
||||
import cy.agorise.graphenej.api.android.NetworkServiceManager;
|
||||
|
||||
/**
|
||||
* Sample application class
|
||||
*/
|
||||
|
||||
public class SampleApplication extends Application implements Application.ActivityLifecycleCallbacks {
|
||||
public class SampleApplication extends Application {
|
||||
private final String TAG = this.getClass().getName();
|
||||
|
||||
/**
|
||||
* Handler instance used to schedule tasks back to the main thread
|
||||
*/
|
||||
private Handler mHandler = new Handler();
|
||||
|
||||
/**
|
||||
* Constant used to specify how long will the app wait for another activity to go through its starting life
|
||||
* cycle events before running the teardownConnectionTask task.
|
||||
*
|
||||
* This is used as a means to detect whether or not the user has left the app.
|
||||
*/
|
||||
private final int DISCONNECT_DELAY = 1500;
|
||||
|
||||
/**
|
||||
* Runnable used to schedule a service disconnection once the app is not visible to the user for
|
||||
* more than DISCONNECT_DELAY milliseconds.
|
||||
*/
|
||||
private final Runnable mDisconnectRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(TAG,"Runing stopService");
|
||||
stopService(new Intent(getApplicationContext(), NetworkService.class));
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Intent intent = new Intent(this, NetworkService.class);
|
||||
startService(intent);
|
||||
|
||||
/*
|
||||
* Registering this class as a listener to all activity's callback cycle events, in order to
|
||||
* better estimate when the user has left the app and it is safe to disconnect the websocket connection
|
||||
*/
|
||||
registerActivityLifecycleCallbacks(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Activity activity, Bundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(Activity activity) {
|
||||
mHandler.removeCallbacks(mDisconnectRunnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(Activity activity) {
|
||||
mHandler.postDelayed(mDisconnectRunnable, DISCONNECT_DELAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {
|
||||
|
||||
registerActivityLifecycleCallbacks(new NetworkServiceManager(this));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import cy.agorise.graphenej.models.JsonRpcResponse;
|
|||
import cy.agorise.graphenej.operations.LimitOrderCreateOperation;
|
||||
import cy.agorise.graphenej.operations.TransferOperation;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.functions.Consumer;
|
||||
|
||||
public class SecondActivity extends AppCompatActivity {
|
||||
|
@ -46,14 +47,17 @@ public class SecondActivity extends AppCompatActivity {
|
|||
|
||||
private Gson gson = new Gson();
|
||||
|
||||
private Disposable mDisposable;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_second);
|
||||
Log.d(TAG,"onCreate");
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
RxBus.getBusInstance()
|
||||
mDisposable = RxBus.getBusInstance()
|
||||
.asFlowable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Consumer<Object>() {
|
||||
|
@ -86,6 +90,12 @@ public class SecondActivity extends AppCompatActivity {
|
|||
unbindService(mConnection);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mDisposable.dispose();
|
||||
}
|
||||
|
||||
/** Defines callbacks for backend binding, passed to bindService() */
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
||||
|
@ -107,25 +117,25 @@ public class SecondActivity extends AppCompatActivity {
|
|||
@OnClick(R.id.transfer_fee_usd)
|
||||
public void onTransferFeeUsdClicked(View v){
|
||||
List<BaseOperation> operations = getTransferOperation();
|
||||
mService.sendMessage(new GetRequiredFees(operations, new Asset("1.3.121")));
|
||||
mService.sendMessage(new GetRequiredFees(operations, new Asset("1.3.121")), GetRequiredFees.REQUIRED_API);
|
||||
}
|
||||
|
||||
@OnClick(R.id.transfer_fee_bts)
|
||||
public void onTransferFeeBtsClicked(View v){
|
||||
List<BaseOperation> operations = getTransferOperation();
|
||||
mService.sendMessage(new GetRequiredFees(operations, new Asset("1.3.0")));
|
||||
mService.sendMessage(new GetRequiredFees(operations, new Asset("1.3.0")), GetRequiredFees.REQUIRED_API);
|
||||
}
|
||||
|
||||
@OnClick(R.id.exchange_fee_usd)
|
||||
public void onExchangeFeeUsdClicked(View v){
|
||||
List<BaseOperation> operations = getExchangeOperation();
|
||||
mService.sendMessage(new GetRequiredFees(operations, new Asset("1.3.121")));
|
||||
mService.sendMessage(new GetRequiredFees(operations, new Asset("1.3.121")), GetRequiredFees.REQUIRED_API);
|
||||
}
|
||||
|
||||
@OnClick(R.id.exchange_fee_bts)
|
||||
public void onExchangeFeeBtsClicked(View v){
|
||||
List<BaseOperation> operations = getExchangeOperation();
|
||||
mService.sendMessage(new GetRequiredFees(operations, new Asset("1.3.0")));
|
||||
mService.sendMessage(new GetRequiredFees(operations, new Asset("1.3.0")), GetRequiredFees.REQUIRED_API);
|
||||
}
|
||||
|
||||
private List<BaseOperation> getTransferOperation(){
|
||||
|
|
Loading…
Reference in a new issue