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

问题描述 投票:1回答:1

我正在我的天蓝色移动应用程序尝试离线同步,但它总是返回空指针。我一直在调试,以达到错误的根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;
    }
}

}

android azure azure-mobile-services
1个回答
0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.