Track Feature failures
SDK can track code-level functions and report issues that may arise during its execution. Please refer Function Tracking section, before continuing with this section.
Feature tracking allows developers to track any feature in the android app by chaining two or more functions.
Take the example of Add To Cart feature in any e-commerce android application. Consider that the function at the time of tapping the AddToCart button is 'addItemToCart' and 'onItemAddedToCart' is the function that gets called after the items have been successfully added to the cart.
Follow the next steps to enable tracking Add to Cart feature for failure,
- First function addItemToCart need to be invoked either using Fn.call() API or using Fn.start() and Fn.end() APIs.
- Second function onItemAddedToCart needs to be invoked using the same API used in step 1.
- Next, chain both the functions using nextFunctionId and nextFunctionClass fields in @Observe annotation of the first function.
- Use expectedChainedExecutionTime field in @Observe annotation to set the expected time it will take to execute the second function after the first function.
Once done, SDK monitors if second function 'onItemAddedToCart' is executed after the execution of first function 'addItemToCart'. If the 'onItemAddedToCart' is not executed within expectedChainedExecutionTime in milliseconds (default value is 2000 milliseconds) then a corresponding issue will be raised.
Method 1 - Using Fn.call() API
- Java
- Kotlin
public class ProductListingActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_listing);
addToCartButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Fn.call("addItemToCart", ProductListingActivity.this, item.getId());
}
});
}
// Here function 'onItemAddedToCart' is expected to be called in under '5000' milliseconds.
@Observe(nextFunctionId = "onItemAddedToCart",
nextFunctionClass = ProductListingActivity.class,
expectedChainedExecutionTime = 5000)
public boolean addItemToCart(String itemId){
if(isValid(itemId)){
...
...
return true;
}
return false;
}
@Override
public void onApiCallComplete(JSONObject response){
if(validResponse(response)){
Fn.call("onItemAddedToCart", ProductListingActivity.this, response.getString("id"));
}
}
@Observe
public void onItemAddedToCart(String itemId){
showMessage(Messages.CARTED_SUCCESS);
}
}
class ProductListingActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_product_listing)
...
...
addToCartButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Fn.call("addItemToCart", this@ProductListingActivity, item.getId())
}
})
}
// Here function 'onItemAddedToCart' is expected to be called in under '5000' milliseconds.
@Observe(nextFunctionId = "onItemAddedToCart",
nextFunctionClass = ProductListingActivity::class,
expectedChainedExecutionTime = 5000)
fun addItemToCart(itemId :String): Boolean{
if(isValid(itemId)){
...
...
return true
}
return false
}
@Override
fun onApiCallComplete(response :JSONObject){
if(validResponse(response)){
Fn.call("onItemAddedToCart", this@ProductListingActivity, response.getString("id"))
}
}
@Observe
fun onItemAddedToCart(itemId :String){
showMessage(Messages.CARTED_SUCCESS)
...
...
}
}
Things to Note:
- Here both functions 'addItemToCart' and 'onItemAddedToCart' are invoked using Fn.call() API.
- Both functions are annotated with @Observe annotation.
- Both functions are chained using 'nextFunctionId' and 'nextFunctionClass' fields in @Observe annotation in the first function.
- Here 'nextFunctionId' is the name/ID of the second function and 'nextFunctionClass' is the .class where the second function is defined.
- 'expectedChainedExecutionTime' in first function 'addItemToCart' overrides time needed to execute second function after execution of first function.
Method 2 - Using Fn.start() and Fn.end() APIs
- Java
- Kotlin
public class ProductListingActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_listing);
addToCartButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addItemToCart(item.getId());
}
});
}
// Here function 'onItemAddedToCart' is expected to be called in under '5000' milliseconds.
@Observe(nextFunctionId = "onItemAddedToCart",
nextFunctionClass = ProductListingActivity.class,
expectedChainedExecutionTime = 5000)
public boolean addItemToCart(String itemId){
Fn.start(new Object(){}, itemId);
if(isValid(itemId)){
...
...
return true;
}
return Fn.end(new Object(){}, false);
}
@Override
public void onApiCallComplete(JSONObject response){
if(validResponse(response)){
onItemAddedToCart(response.getString("id"));
}
}
@Observe
public void onItemAddedToCart(String itemId){
Fn.start(new Object(){}, itemId);
showMessage(Messages.CARTED_SUCCESS);
Fn.end(new Object(){});
}
}
class ProductListingActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_product_listing)
...
...
addToCartButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addItemToCart(item.getId())
}
})
}
// Here function 'onItemAddedToCart' is expected to be called in under '5000' milliseconds.
@Observe(nextFunctionId = "onItemAddedToCart",
nextFunctionClass = ProductListingActivity::class,
expectedChainedExecutionTime = 5000)
fun addItemToCart(itemId :String): Boolean{
Fn.start(object : Object() {}, itemId)
if(isValid(itemId)){
...
...
return true
}
return Fn.end(object: Object(){}, false)
}
@Override
fun onApiCallComplete(response :JSONObject){
if(validResponse(response)){
onItemAddedToCart(response.getString("id"))
}
}
@Observe
fun onItemAddedToCart(itemId :String){
Fn.start(object : Object() {}, itemId)
showMessage(Messages.CARTED_SUCCESS)
...
...
Fn.end(object: Object(){})
}
}
Things to Note:
- Both functions 'addItemToCart' and 'onItemAddedToCart' are annotated with @Observe annotation.
- Both functions are chained using 'nextFunctionId' and 'nextFunctionClass' fields in @Observe annotation in the first function.
- Here 'nextFunctionId' is the name/ID of the second function and 'nextFunctionClass' is the .class where the second function is defined.
- 'expectedChainedExecutionTime' in first function 'addItemToCart' overrides time (default is 2000 milliseconds) expected to execute second function after execution of first function.
@Observe fields
Chain two functions using nextFunctionId, nextFunctionClass, expectedChainedExecutionTime fields in @Observe.
Next Function Id
Provide the name/ID of the second function in the nextFunctionId field in the @Observe annotation that is to be chained with the first function.
Next Function Class
Provide the .class (e.g ClassName.class) where second function is defined. Use nextFunctionClass field in the @Observe annotation to set the value.
Expected Chained Execution Time
When two functions are chained, expectedChainedExecutionTime field in @Observe determines the expected time between the execution of two functions.
Issue will be reported to the dashboard if the second function is not called within the expected time after the execution of the first function.
Default time is 2000 milliseconds.