这是我的LOgcat:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.app.Dialog.<init>(Dialog.java:108)
at android.app.AlertDialog.<init>(AlertDialog.java:125)
at android.app.AlertDialog$Builder.create(AlertDialog.java:967)
at com.example.todolistpushkaran.ToDoActivity.createAndShowDialog(ToDoActivity.java:268)
at com.example.todolistpushkaran.ToDoActivity.createAndShowDialog(ToDoActivity.java:252)
at com.example.todolistpushkaran.ToDoActivity.access$300(ToDoActivity.java:31)
at com.example.todolistpushkaran.ToDoActivity$3.doInBackground(ToDoActivity.java:229)
at com.example.todolistpushkaran.ToDoActivity$3.doInBackground(ToDoActivity.java:211)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
这是我的ToDoActivity.java类
package com.example.todolistpushkaran;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import com.microsoft.windowsazure.mobileservices.MobileServiceClient;
import com.microsoft.windowsazure.mobileservices.http.NextServiceFilterCallback;
import com.microsoft.windowsazure.mobileservices.http.ServiceFilter;
import com.microsoft.windowsazure.mobileservices.http.ServiceFilterRequest;
import com.microsoft.windowsazure.mobileservices.http.ServiceFilterResponse;
import com.microsoft.windowsazure.mobileservices.table.MobileServiceTable;
import java.net.MalformedURLException;
import java.util.List;
import static com.microsoft.windowsazure.mobileservices.table.query.QueryOperations.val;
public class ToDoActivity extends Activity {
/**
* Mobile Service Client reference
*/
private MobileServiceClient mClient;
/**
* Mobile Service Table used to access data
*/
private MobileServiceTable<ToDoItem> 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://todolistpushkaran.azure-mobile.net/",
"My_Password_Here",
this).withFilter(new ProgressFilter());
// Get the Mobile Service Table instance to use
mToDoTable = mClient.getTable(ToDoItem.class);
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");
}
}
/**
* 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);
new AsyncTask<Void, Void, Void>()
{
@Override
protected Void doInBackground(Void... params)
{
try
{
final ToDoItem entity = mToDoTable.update(item).get();
runOnUiThread(new Runnable() {
@Override
public void run() {
if (entity.isComplete()) {
mAdapter.remove(entity);
}
}
});
} catch (Exception e){
createAndShowDialog(e, "Error");
}
return null;
}
}.execute();
}
/**
* 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
new AsyncTask<Void, Void, Void>(){
@Override
protected Void doInBackground(Void... params) {
try {
final ToDoItem entity = mToDoTable.insert(item).get();
runOnUiThread(new Runnable() {
@Override
public void run() {
if(!entity.isComplete()){
mAdapter.add(entity);
}
}
});
} catch (Exception e){
createAndShowDialog(e, "Error");
}
return null;
}
}.execute();
mTextNewToDo.setText("");
}
/**
* Refresh the list with the items in the Mobile Service Table
*/
private void refreshItemsFromTable() {
// Get the items that weren't marked as completed and add them in the
// adapter
new AsyncTask<Void, Void, Void>(){
@Override
protected Void doInBackground(Void... params) {
try {
final List<ToDoItem> results =
mToDoTable.where().field("complete").
eq(val(false)).execute().get();
runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.clear();
for(ToDoItem item : results){
mAdapter.add(item);
}
}
});
} catch (Exception e){
createAndShowDialog(e, "Error");
}
return null;
}
}.execute();
}
/**
* 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();
}
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;
}
}
}
请帮忙!
答案 0 :(得分:1)
您正在非ui线程中调用createAndShowDialog(e, "Error");
。
改变它:
runOnUiThread(new Runnable(){
public void run(){
createAndShowDialog(e, "Error");
}
});
或者在onPostExecute中添加createAndShowDialog(e, "Error");
。