在线azure表工作但离线不工作

时间:2018-04-20 15:18:37

标签: android azure azure-mobile-services

我正在我的天蓝色移动应用程序中尝试离线同步但它总是返回空指针。我一直在调试以达到错误的根目录3天但无法弄明白。任何帮助都将受到高度赞赏。每次我调试我得到此错误,我已按照Microsoft azre提供的相同步骤进行操作。

我的班级是

  public class User {

@com.google.gson.annotations.SerializedName("id")
private String mId;
@com.google.gson.annotations.SerializedName("phonenumber")
private String mText;


@com.google.gson.annotations.SerializedName("email")
private boolean mComplete;
@com.google.gson.annotations.SerializedName("name")
private String mName;

public User() {

}

@Override
public String toString() {
    return getText();
}


public User(String text, String id) {
    this.setText(text);
    this.setId(id);
}


public String getText() {
    return mText;
}


public final void setText(String text) {
    mText = text;
}


public String getId() {
    return mId;
}


public final void setId(String id) {
    mId = id;
}


public boolean isComplete() {
    return mComplete;
}

public void setComplete(boolean complete) {
    mComplete = complete;
}

@Override
public boolean equals(Object o) {
    return o instanceof User && ((User) o).mId == mId;
}}

我的活动是

公共类ToDoActivity扩展了Activity {

/**
 * Mobile Service Client reference
 */
private MobileServiceClient mClient;



//Offline Sync
/**
 * Mobile Service Table used to access and Sync data
 */
private MobileServiceSyncTable<User> mToDoTable;

/**
 * Adapter to sync the items list with the view
 */
private ToDoItemAdapter mAdapter;

/**
 * EditText containing the "New To Do" text
 */
private EditText mTextNewToDo;

/**
 * Progress spinner to use for table operations
 */
private ProgressBar mProgressBar;

/**
 * Initializes the activity
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_to_do);

    mProgressBar = (ProgressBar) findViewById(R.id.loadingProgressBar);

    // Initialize the progress bar
    mProgressBar.setVisibility(ProgressBar.GONE);

    try {
        // Create the Mobile Service Client instance, using the provided

        // Mobile Service URL and key
        mClient = new MobileServiceClient(
                "https://housewrench.azurewebsites.net",
                this).withFilter(new ProgressFilter());

        // Extend timeout from default of 10s to 20s
        mClient.setAndroidHttpClientFactory(new OkHttpClientFactory() {
            @Override
            public OkHttpClient createOkHttpClient() {
                OkHttpClient client = new OkHttpClient();
                client.setReadTimeout(20, TimeUnit.SECONDS);
                client.setWriteTimeout(20, TimeUnit.SECONDS);
                return client;
            }
        });

        // Get the Mobile Service Table instance to use

       // mToDoTable = mClient.getTable(ToDoItem.class);
       // mUserTable = mClient.getTable(User.class);

        // Offline Sync
       mToDoTable = mClient.getSyncTable("User", User.class);

        //Init local storage
        initLocalStore().get();

        mTextNewToDo = (EditText) findViewById(R.id.textNewToDo);

        // Create an adapter to bind the items with the view
        mAdapter = new ToDoItemAdapter(this, R.layout.row_list_to_do);
        ListView listViewToDo = (ListView) findViewById(R.id.listViewToDo);
        listViewToDo.setAdapter(mAdapter);

        // Load the items from the Mobile Service
        refreshItemsFromTable();

    } catch (MalformedURLException e) {
        createAndShowDialog(new Exception("There was an error creating the Mobile Service. Verify the URL"), "Error");
    } catch (Exception e){
        createAndShowDialog(e, "Error");
    }
}

/**
 * Initializes the activity menu
 */
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

/**
 * Select an option from the menu
 */
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.menu_refresh) {
        refreshItemsFromTable();
    }

    return true;
}

/**
 * Mark an item as completed
 *
 * @param item
 *            The item to mark
 */
public void checkItem(final ToDoItem item) {
    if (mClient == null) {
        return;
    }

    // Set the item as completed and update it in the table
    item.setComplete(true);

    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
        @Override
        protected Void doInBackground(Void... params) {
            try {

                checkItemInTable(item);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (item.isComplete()) {
                            mAdapter.remove(item);
                        }
                    }
                });
            } catch (final Exception e) {
                createAndShowDialogFromTask(e, "Error");
            }

            return null;
        }
    };

    runAsyncTask(task);

}

/**
 * Mark an item as completed in the Mobile Service Table
 *
 * @param item
 *            The item to mark
 */
public void checkItemInTable(ToDoItem item) throws ExecutionException, InterruptedException {
    //mToDoTable.update(item).get();
}

/**
 * Add a new item
 *
 * @param view
 *            The view that originated the call
 */
public void addItem(View view) {
    if (mClient == null) {
        return;
    }

    // Create a new item
    final ToDoItem item = new ToDoItem();

    item.setText(mTextNewToDo.getText().toString());
    item.setComplete(false);

    // Insert the new item
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
        @Override
        protected Void doInBackground(Void... params) {
            try {
                final ToDoItem entity = addItemInTable(item);

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if(!entity.isComplete()){
                            mAdapter.add(entity);
                        }
                    }
                });
            } catch (final Exception e) {
                createAndShowDialogFromTask(e, "Error");
            }
            return null;
        }
    };

    runAsyncTask(task);

    mTextNewToDo.setText("");
}

/**
 * Add an item to the Mobile Service Table
 *
 * @param item
 *            The item to Add
 */
public ToDoItem addItemInTable(ToDoItem item) throws ExecutionException, InterruptedException {
   // ToDoItem entity = mToDoTable.insert(item).get();
    return item;
}

/**
 * Refresh the list with the items in the Table
 */
    private void refreshItemsFromTable() {

    // Get the items that weren't marked as completed and add them in the
    // adapter

    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
        @Override
        protected Void doInBackground(Void... params) {

            try {
                //final List<User> results = refreshItemsFromMobileServiceTable();

                //Offline Sync
                final List<User> results = refreshItemsFromMobileServiceTableSyncTable();

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mAdapter.clear();

                        for (User item : results) {
                            //mAdapter.add(item);
                        }
                    }
                });
            } catch (final Exception e){
                createAndShowDialogFromTask(e, "Error");
            }

            return null;
        }
    };

    runAsyncTask(task);
}

/**
 * Refresh the list with the items in the Mobile Service Table
 */

        private List<User> refreshItemsFromMobileServiceTable() throws 
       ExecutionException, InterruptedException {
    return mUserTable.where().field("name").
            eq(val("noor")).execute().get();
}

//Offline Sync
/**
 * Refresh the list with the items in the Mobile Service Sync Table
 */
   private List<User> refreshItemsFromMobileServiceTableSyncTable() throws 
  ExecutionException, InterruptedException {
    //sync the data
    sync().get();
    Query query = QueryOperations.field("phonenumber").
            eq(val(false));
    return mToDoTable.read(query).get();
}

/**
 * Initialize local storage
 * @return
 * @throws MobileServiceLocalStoreException
 * @throws ExecutionException
 * @throws InterruptedException
 */
private AsyncTask<Void, Void, Void> initLocalStore() throws MobileServiceLocalStoreException, ExecutionException, InterruptedException {

    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {

                MobileServiceSyncContext syncContext = mClient.getSyncContext();

                if (syncContext.isInitialized())
                    return null;

                SQLiteLocalStore localStore = new SQLiteLocalStore(mClient.getContext(), "MyStore", null, 1);

                Map<String, ColumnDataType> tableDefinition = new HashMap<String, ColumnDataType>();
                tableDefinition.put("id", ColumnDataType.String);
                tableDefinition.put("phonenumber", ColumnDataType.String);
                tableDefinition.put("name", ColumnDataType.String);
                tableDefinition.put("email", ColumnDataType.String);

                localStore.defineTable("User", tableDefinition);

                SimpleSyncHandler handler = new SimpleSyncHandler();

                syncContext.initialize(localStore, handler).get();

            } catch (final Exception e) {
                createAndShowDialogFromTask(e, "Error");
            }

            return null;
        }
    };

    return runAsyncTask(task);
}

//Offline Sync
/**
 * Sync the current context and the Mobile Service Sync Table
 * @return
 */

private AsyncTask<Void, Void, Void> sync() {
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
        @Override
        protected Void doInBackground(Void... params) {
            try {
                MobileServiceSyncContext syncContext = mClient.getSyncContext();
                syncContext.push().get();
                mToDoTable.pull(null).get();
            } catch (final Exception e) {
                createAndShowDialogFromTask(e, "Error");
            }
            return null;
        }
    };
    return runAsyncTask(task);
}


/**
 * Creates a dialog and shows it
 *
 * @param exception
 *            The exception to show in the dialog
 * @param title
 *            The dialog title
 */
private void createAndShowDialogFromTask(final Exception exception, String title) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            createAndShowDialog(exception, "Error");
        }
    });
}


/**
 * Creates a dialog and shows it
 *
 * @param exception
 *            The exception to show in the dialog
 * @param title
 *            The dialog title
 */
private void createAndShowDialog(Exception exception, String title) {
    Throwable ex = exception;
    if(exception.getCause() != null){
        ex = exception.getCause();
    }
    createAndShowDialog(ex.getMessage(), title);
}

/**
 * Creates a dialog and shows it
 *
 * @param message
 *            The dialog message
 * @param title
 *            The dialog title
 */
private void createAndShowDialog(final String message, final String title) {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);

    builder.setMessage(message);
    builder.setTitle(title);
    builder.create().show();
}

/**
 * Run an ASync task on the corresponding executor
 * @param task
 * @return
 */
private AsyncTask<Void, Void, Void> runAsyncTask(AsyncTask<Void, Void, Void> task) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        return task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    } else {
        return task.execute();
    }
}

private class ProgressFilter implements ServiceFilter {

    @Override
    public ListenableFuture<ServiceFilterResponse> handleRequest(ServiceFilterRequest request, NextServiceFilterCallback nextServiceFilterCallback) {

        final SettableFuture<ServiceFilterResponse> resultFuture = SettableFuture.create();


        runOnUiThread(new Runnable() {

            @Override
            public void run() {
                if (mProgressBar != null) mProgressBar.setVisibility(ProgressBar.VISIBLE);
            }
        });

        ListenableFuture<ServiceFilterResponse> future = nextServiceFilterCallback.onNext(request);

        Futures.addCallback(future, new FutureCallback<ServiceFilterResponse>() {
            @Override
            public void onFailure(Throwable e) {
                resultFuture.setException(e);
            }

            @Override
            public void onSuccess(ServiceFilterResponse response) {
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        if (mProgressBar != null) mProgressBar.setVisibility(ProgressBar.GONE);
                    }
                });

                resultFuture.set(response);
            }
        });

        return resultFuture;
    }
}

}

1 个答案:

答案 0 :(得分:0)

根据您的代码,您似乎已关注Azure mobile apps quickstart sample for android并将ToDoItem调整为User。我注意到您没有为name列设置正确的getter和setter,并且email列的定义是String,但是您将其分配给布尔mComplete。

我建议您检查一下ToDoItem表的离线同步是否正确。并且您最好为catch代码块设置断点,以查看哪个任务抛出异常并检查相关代码以缩小此问题。如果您无法解决此问题,可以使用引发异常的特定代码行更新您的问题,并为我们解决此问题的详细异常信息。