Created ConnectedFragment, that encapsulates the repeated code which encapsulates the repeated code Fragmets that connect to the NetworkService use. Simplified SendTransactionFragment by extending the newly created ConnectedFragment.
This commit is contained in:
parent
10014263d7
commit
4e64b10014
3 changed files with 124 additions and 71 deletions
|
@ -27,7 +27,6 @@ import org.bitcoinj.core.ECKey
|
|||
import java.util.ArrayList
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
// TODO Add method to load the 20? most important assets
|
||||
// TODO add progress bar or something while the user waits for the import response from the node
|
||||
|
||||
class ImportBrainkeyActivity : ConnectedActivity() {
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package cy.agorise.bitsybitshareswallet.fragments
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import cy.agorise.graphenej.api.ConnectionStatusUpdate
|
||||
import cy.agorise.graphenej.api.android.NetworkService
|
||||
import cy.agorise.graphenej.api.android.RxBus
|
||||
import cy.agorise.graphenej.models.JsonRpcResponse
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
||||
/**
|
||||
* Base fragment that defines the methods and variables commonly used in all fragments that directly connect and
|
||||
* talk to the BitShares nodes through graphenej's NetworkService
|
||||
*/
|
||||
abstract class ConnectedFragment: Fragment(), ServiceConnection {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "ConnectedFragment"
|
||||
}
|
||||
|
||||
/** Network service connection */
|
||||
protected var mNetworkService: NetworkService? = null
|
||||
|
||||
/** Flag used to keep track of the NetworkService binding state */
|
||||
private var mShouldUnbindNetwork: Boolean = false
|
||||
|
||||
/** Keeps track of all RxJava disposables, to make sure they are all disposed when the fragment is destroyed */
|
||||
protected var mDisposables = CompositeDisposable()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// Connect to the RxBus, which receives events from the NetworkService
|
||||
mDisposables.add(
|
||||
RxBus.getBusInstance()
|
||||
.asFlowable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { handleIncomingMessage(it) }
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleIncomingMessage(message: Any?) {
|
||||
if (message is JsonRpcResponse<*>) {
|
||||
// Generic processing taken care by subclasses
|
||||
handleJsonRpcResponse(message)
|
||||
} else if (message is ConnectionStatusUpdate) {
|
||||
// Generic processing taken care by subclasses
|
||||
handleConnectionStatusUpdate(message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
val intent = Intent(context, NetworkService::class.java)
|
||||
if (context?.bindService(intent, this, Context.BIND_AUTO_CREATE) == true) {
|
||||
mShouldUnbindNetwork = true
|
||||
} else {
|
||||
Log.e(TAG, "Binding to the network service failed.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
// Unbinding from network service
|
||||
if (mShouldUnbindNetwork) {
|
||||
context?.unbindService(this)
|
||||
mShouldUnbindNetwork = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
if (!mDisposables.isDisposed) mDisposables.dispose()
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) { }
|
||||
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
||||
val binder = service as NetworkService.LocalBinder
|
||||
mNetworkService = binder.service
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to be implemented by all subclasses in order to be notified of JSON-RPC responses.
|
||||
* @param response
|
||||
*/
|
||||
abstract fun handleJsonRpcResponse(response: JsonRpcResponse<*>)
|
||||
|
||||
/**
|
||||
* Method to be implemented by all subclasses in order to be notified of connection status updates
|
||||
* @param connectionStatusUpdate
|
||||
*/
|
||||
abstract fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate)
|
||||
}
|
|
@ -1,13 +1,8 @@
|
|||
package cy.agorise.bitsybitshareswallet.fragments
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import android.preference.PreferenceManager
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
|
@ -15,7 +10,6 @@ import android.widget.AdapterView
|
|||
import android.widget.Toast
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
|
@ -32,8 +26,6 @@ import cy.agorise.bitsybitshareswallet.utils.*
|
|||
import cy.agorise.bitsybitshareswallet.viewmodels.BalanceDetailViewModel
|
||||
import cy.agorise.graphenej.*
|
||||
import cy.agorise.graphenej.api.ConnectionStatusUpdate
|
||||
import cy.agorise.graphenej.api.android.NetworkService
|
||||
import cy.agorise.graphenej.api.android.RxBus
|
||||
import cy.agorise.graphenej.api.calls.BroadcastTransaction
|
||||
import cy.agorise.graphenej.api.calls.GetAccountByName
|
||||
import cy.agorise.graphenej.api.calls.GetDynamicGlobalProperties
|
||||
|
@ -43,7 +35,6 @@ import cy.agorise.graphenej.models.DynamicGlobalProperties
|
|||
import cy.agorise.graphenej.models.JsonRpcResponse
|
||||
import cy.agorise.graphenej.operations.TransferOperationBuilder
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.android.synthetic.main.fragment_send_transaction.*
|
||||
import me.dm7.barcodescanner.zxing.ZXingScannerView
|
||||
|
@ -57,7 +48,7 @@ import java.util.Locale
|
|||
import java.util.concurrent.TimeUnit
|
||||
import javax.crypto.AEADBadTagException
|
||||
|
||||
class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, ServiceConnection {
|
||||
class SendTransactionFragment : ConnectedFragment(), ZXingScannerView.ResultHandler {
|
||||
private val TAG = this.javaClass.simpleName
|
||||
|
||||
// Camera Permission
|
||||
|
@ -86,14 +77,6 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv
|
|||
/** User account to which send the funds */
|
||||
private var mSelectedUserAccount: UserAccount? = null
|
||||
|
||||
private var mDisposables = CompositeDisposable()
|
||||
|
||||
/* Network service connection */
|
||||
private var mNetworkService: NetworkService? = null
|
||||
|
||||
/** Flag used to keep track of the NetworkService binding state */
|
||||
private var mShouldUnbindNetwork: Boolean = false
|
||||
|
||||
// Map used to keep track of request and response id pairs
|
||||
private val responseMap = HashMap<Long, Int>()
|
||||
|
||||
|
@ -213,34 +196,26 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv
|
|||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { validateAmount(it!!) }
|
||||
)
|
||||
|
||||
// Connect to the RxBus, which receives events from the NetworkService
|
||||
mDisposables.add(
|
||||
RxBus.getBusInstance()
|
||||
.asFlowable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { handleIncomingMessage(it) }
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleIncomingMessage(message: Any?) {
|
||||
if (message is JsonRpcResponse<*>) {
|
||||
if (responseMap.containsKey(message.id)) {
|
||||
val responseType = responseMap[message.id]
|
||||
when (responseType) {
|
||||
RESPONSE_GET_ACCOUNT_BY_NAME -> handleAccountName(message.result)
|
||||
RESPONSE_GET_DYNAMIC_GLOBAL_PARAMETERS -> handleDynamicGlobalProperties(message.result)
|
||||
RESPONSE_GET_REQUIRED_FEES -> handleRequiredFees(message.result)
|
||||
RESPONSE_BROADCAST_TRANSACTION -> handleBroadcastTransaction(message)
|
||||
}
|
||||
responseMap.remove(message.id)
|
||||
}
|
||||
} else if (message is ConnectionStatusUpdate) {
|
||||
if (message.updateCode == ConnectionStatusUpdate.DISCONNECTED) {
|
||||
// If we got a disconnection notification, we should clear our response map, since
|
||||
// all its stored request ids will now be reset
|
||||
responseMap.clear()
|
||||
override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) {
|
||||
if (responseMap.containsKey(response.id)) {
|
||||
val responseType = responseMap[response.id]
|
||||
when (responseType) {
|
||||
RESPONSE_GET_ACCOUNT_BY_NAME -> handleAccountName(response.result)
|
||||
RESPONSE_GET_DYNAMIC_GLOBAL_PARAMETERS -> handleDynamicGlobalProperties(response.result)
|
||||
RESPONSE_GET_REQUIRED_FEES -> handleRequiredFees(response.result)
|
||||
RESPONSE_BROADCAST_TRANSACTION -> handleBroadcastTransaction(response)
|
||||
}
|
||||
responseMap.remove(response.id)
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate) {
|
||||
if (connectionStatusUpdate.updateCode == ConnectionStatusUpdate.DISCONNECTED) {
|
||||
// If we got a disconnection notification, we should clear our response map, since
|
||||
// all its stored request ids will now be reset
|
||||
responseMap.clear()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -481,39 +456,12 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv
|
|||
super.onResume()
|
||||
if (isCameraPreviewVisible)
|
||||
startCameraPreview()
|
||||
|
||||
val intent = Intent(context, NetworkService::class.java)
|
||||
if (context?.bindService(intent, this, Context.BIND_AUTO_CREATE) == true) {
|
||||
mShouldUnbindNetwork = true
|
||||
} else {
|
||||
Log.e(TAG, "Binding to the network service failed.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
// Unbinding from network service
|
||||
if (mShouldUnbindNetwork) {
|
||||
context?.unbindService(this)
|
||||
mShouldUnbindNetwork = false
|
||||
}
|
||||
|
||||
if (!isCameraPreviewVisible)
|
||||
stopCameraPreview()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
if (!mDisposables.isDisposed) mDisposables.dispose()
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) { }
|
||||
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
||||
val binder = service as NetworkService.LocalBinder
|
||||
mNetworkService = binder.service
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue