不能在Android项目中的UI线程上调用错误等待

时间:2016-05-03 15:33:03

标签: android multithreading android-fragments

我目前正在尝试从谷歌驱动器中读取数据,然后使用查询然后将gson传输到片段,这样我就可以将所述片段的编辑文本值设置为正在读取的gson(如果你遵循那个,那就是Kudos!)< / p>

每次我打开片段时,都会收到以下错误消息:

  05-03 16:12:39.311 12594-12594/com.example.fitness_first.fitnessfirst E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                    Process: com.example.fitness_first.fitnessfirst, PID: 12594
                                                                                    java.lang.IllegalStateException: await must not be called on the UI thread
                                                                                        at com.google.android.gms.common.internal.zzx.zza(Unknown Source)
                                                                                        at com.google.android.gms.common.api.internal.zzb.await(Unknown Source)
                                                                                        at com.example.fitness_first.fitnessfirst.ReadFileInAppFolder$1.onResult(ReadFileInAppFolder.java:63)
                                                                                        at com.example.fitness_first.fitnessfirst.ReadFileInAppFolder$1.onResult(ReadFileInAppFolder.java:50)
                                                                                        at com.google.android.gms.common.api.internal.zzb$zza.zzb(Unknown Source)
                                                                                        at com.google.android.gms.common.api.internal.zzb$zza.handleMessage(Unknown Source)
                                                                                        at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                        at android.os.Looper.loop(Looper.java:148)
                                                                                        at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

我认为通过设置一个新线程来处理数据线程本身它会否定这个问题,但唉不是这样的。任何指针都将受到赞赏

加载详细信息活动:

 package com.example.fitness_first.fitnessfirst;

 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.util.Log;
 import android.widget.ProgressBar;

 import com.google.android.gms.common.api.ResultCallback;
 import com.google.android.gms.drive.Drive;
 import com.google.android.gms.drive.DriveApi;
 import com.google.android.gms.drive.DriveFile;
 import com.google.android.gms.drive.DriveId;
 import com.google.android.gms.drive.MetadataBuffer;
 import com.google.android.gms.drive.query.Filter;
 import com.google.android.gms.drive.query.Filters;
 import com.google.android.gms.drive.query.Query;
 import com.google.android.gms.drive.query.SearchableField;
 import com.google.gson.Gson;

 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;

 public class ReadFileInAppFolder extends MainActivity {

UserDetails result1;
Gson gson = new Gson();
Bundle connectionHint;

@Override
protected void onCreate(Bundle b) {
    super.onCreate(b);
}

public void retrieveUserDetails() {
    DataThread runner = new DataThread();
    runner.start();
}

@Override
public void onConnected(Bundle connectionHint) {
    super.onConnected(connectionHint);

    Filter starredFilter = Filters.eq(SearchableField.STARRED, true);
    Filter mimeTypeFilter = Filters.eq(SearchableField.MIME_TYPE, "application/json");
    Filter titleFilter = Filters.contains(SearchableField.TITLE, "appconfig.json");
    Query query = new Query.Builder().addFilter(starredFilter).addFilter(mimeTypeFilter).addFilter(titleFilter).build();

    Drive.DriveApi.getAppFolder(mGoogleApiClient).queryChildren(mGoogleApiClient, query)
            .setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
                @Override
                public void onResult(DriveApi.MetadataBufferResult result) {
                    if (!result.getStatus().isSuccess()) {
                        Log.i(TAG, "Problem while retrieving results");
                        return;
                    }


                    MetadataBuffer metadataBuffer = result.getMetadataBuffer();
                    DriveId driveId = metadataBuffer.get(0).getDriveId();
                    DriveFile file = driveId.asDriveFile();
                    DriveApi.DriveContentsResult driveContentsResult =
                            file.open(mGoogleApiClient, DriveFile.MODE_READ_ONLY, null).await();

                    if (!driveContentsResult.getStatus().isSuccess()) {
                        driveContentsResult = null;
                    }

                    InputStream inputStream = driveContentsResult.getDriveContents().getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                    result1 = gson.fromJson(reader, UserDetails.class);

                    Bundle bundle = new Bundle();
                    android.os.Message message = AccountFragment.dataHandler.obtainMessage();

                    try {
                        Thread.sleep(1000);
                        bundle.putString("NAME", result1.toString());
                        message.setData(bundle);
                        AccountFragment.dataHandler.sendMessage(message);

                    } catch (InterruptedException e) {
                        Log.i(TAG, "Data thread interrupted");
                    }

                }
            });
}

private class DataThread extends Thread implements Runnable {
    @Override
    public void run()

    {
        Log.i("Data Thread", "Starting");
        onConnected(connectionHint);
        Log.i("Data Thread", "Finshed");

    }
}

我想要传递数据的片段:

 package com.example.fitness_first.fitnessfirst;

 import android.content.Intent;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.support.v4.app.Fragment;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.Spinner;

 import com.google.android.gms.common.api.GoogleApiClient;
 import com.google.android.gms.nearby.messages.Message;


 public class AccountFragment extends Fragment implements View.OnClickListener{

public static GoogleApiClient getInstance() {
    return null;
}

private String activityName = "Account management";

private Button saveDetailsButton;
private static EditText accountName;
private EditText accountUserName;
private EditText accountHeight;
private EditText accountWeight;
private Spinner spinnerGender = null;

private Bundle name = new Bundle();
private String nameKey = "NAME";
private Bundle userName = new Bundle();
private String usernameKey = "USERNAME";
private Bundle gender = new Bundle();
private String genderKey = "GENDER";
private Bundle height = new Bundle();
private String heightKey = "HEIGHT";
private Bundle weight = new Bundle();
private String weightKey = "WEIGHT";
public static Intent detailsIntent = new Intent();

private final int   spinnerPosMALE    = 0;
private final int   spinnerPosFEMALE  = 1;


public AccountFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.your_account, container, false);
    saveDetailsButton = (Button) rootView.findViewById(R.id.buttonSaveDetails);
    saveDetailsButton.setOnClickListener(this);
    accountName = (EditText) rootView.findViewById(R.id.editTextName);
    accountUserName = (EditText) rootView.findViewById(R.id.editTextUsername);
    spinnerGender   = (Spinner)  rootView.findViewById(R.id.spinnerGender);
    accountHeight = (EditText) rootView.findViewById(R.id.editTextHeight);
    accountWeight = (EditText) rootView.findViewById(R.id.editTextWeight);


    super.onCreateView(inflater, container, savedInstanceState);
    return rootView;
}

@Override
public void onClick(View v) {

    name.putString("NAME", accountName.getText().toString());
    userName.putString("USERNAME", accountUserName.getText().toString());
    gender.putString("GENDER", spinnerGender.getSelectedItem().toString());
    height.putString("HEIGHT", accountHeight.getText().toString());
    weight.putString("WEIGHT", accountWeight.getText().toString());

    detailsIntent.putExtras(name);
    detailsIntent.putExtras(userName);
    detailsIntent.putExtras(gender);
    detailsIntent.putExtras(height);
    detailsIntent.putExtras(weight);

    CreateFileInAppFolderActivity saveDetails = new CreateFileInAppFolderActivity();
    saveDetails.saveDetails(detailsIntent);
}

@Override
public void onPause() {
    super.onPause();
    Log.i(activityName, "Paused");
}

@Override
public void onResume() {
    super.onResume();

    ReadFileInAppFolder dataIn = new ReadFileInAppFolder();
    dataIn.retrieveUserDetails();
    Log.i(activityName, "Resumed");
}

@Override
public void onStop() {
    super.onStop();
    Log.i(activityName, "Stopped");
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.i(activityName, "Destroyed");
}

public static Handler dataHandler = new Handler()
{
    @Override
    public void handleMessage(android.os.Message message){
        String s = message.getData().getString("NAME");
        accountName.setText(s);
    }
};
}

1 个答案:

答案 0 :(得分:0)

如异常消息中所述,您不应在UI线程上使用await。 设置新线程来处理数据应该修复它。

[编辑1]

https://developers.google.com/android/reference/com/google/android/gms/common/api/ResultCallback#public-method-summary

中所述,在UI线程上调用“onResult”函数
  

public abstract void onResult(R result)

     

结果准备就绪时调用。

     

回调的责任是释放任何资源   与结果相关联。某些结果类型可能会实现   可释放的,在这种情况下应该使用release()来释放   相关资源。

     

此方法在主线程上调用,除非被重写   setHandler(处理程序)。