@Kroll.method
 public void insertRowAfter(
     int index, Object data, @Kroll.argument(optional = true) KrollDict options) {
   TiContext ctx = getTiContext();
   if (ctx == null) {
     Log.w(LCAT, "Context has been GC'd, not inserting row.");
     return;
   }
   if (ctx.isUIThread()) {
     handleInsertRowAfter(index, data);
     return;
   }
   sendBlockingUiMessage(MSG_INSERT_ROW, data, INSERT_ROW_AFTER, index);
 }
  @Kroll.method
  public void appendRow(Object row, @Kroll.argument(optional = true) KrollDict options) {
    TiContext ctx = getTiContext();
    if (ctx == null) {
      Log.w(LCAT, "Context has been GC'd, not appending row");
      return;
    }
    if (ctx.isUIThread()) {
      handleAppendRow(row);
      return;
    }

    sendBlockingUiMessage(MSG_APPEND_ROW, row);
  }
 @Kroll.method
 public void deleteRow(int index, @Kroll.argument(optional = true) KrollDict options) {
   TiContext ctx = getTiContext();
   if (ctx == null) {
     Log.w(LCAT, "Context has been GC'd, not deleting row.");
     return;
   }
   if (ctx.isUIThread()) {
     handleDeleteRow(index);
     return;
   }
   Message msg = getUIHandler().obtainMessage(MSG_DELETE_ROW);
   msg.arg1 = index;
   msg.sendToTarget();
 }
 @Kroll.setProperty
 @Kroll.method
 public void setData(Object[] data, @Kroll.argument(optional = true) KrollDict options) {
   TiContext ctx = getTiContext();
   Object[] actualData = data;
   if (data != null && data.length > 0 && data[0] instanceof Object[]) {
     actualData = (Object[]) data[0];
   }
   if (ctx == null) {
     Log.w(LCAT, "Context has been GC'd, not setting table data.");
     return;
   }
   if (ctx.isUIThread()) {
     handleSetData(actualData);
   } else {
     sendBlockingUiMessage(MSG_SET_DATA, actualData);
   }
 }