从异步更新 UiThread 上的 TextView - Android

Update TextView on UiThread from Async - Android

我正在使用 OkHttp3 进行 GET API 调用,这有效,但是我想用 GET 调用的结果更新 UiThread 中的 TextView (jsonTextView)。

我尝试了10种不同的方法,但都不起作用。总是告诉我无法解决这个或那个,因此我要求如果您决定帮助我,请考虑发布对您的答案的任何依赖项,例如导入或声明。

我在休息时留了一行class:"CODE TO UPDATE jsonTextView IN UITHREAD"。您认为实现此目标的最佳方法是什么?

非常感谢你,我已经为此浪费了时间。

这是我的activity

package it.test.test;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;

import android.os.*;

import android.util.Log;

public class MainActivity extends AppCompatActivity {

    Button fetchUpdateButton;
    TextView jsonTextView;
    EditText assetCode;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        fetchUpdateButton = (Button) findViewById(R.id.fetchUpdateButton);
        fetchUpdateButton.setOnClickListener(fetchAssetUpdateClick);

        jsonTextView = (TextView) findViewById(R.id.jsonTextView);
        assetCode = (EditText) findViewById(R.id.assetCode);

    }

    View.OnClickListener fetchAssetUpdateClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            REST r = new REST();

            try {

                r.getAssetUpdates(assetCode.getText().toString());

            } catch (Exception e) {

                e.printStackTrace();
                jsonTextView.setText("API Fetch Failed");

            }

        }
    };
}

这是我的 REST class

package it.test.test;

import android.util.Log;

import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;


/**
 * Created by fabio on 25/02/2017.
 */

public class REST  {

    private final OkHttpClient client = new OkHttpClient();

    public void getAssetUpdates(String assetCode) throws Exception {
        Request request = new Request.Builder()
                .url("http://10.0.0.3:8080/api/api/assets/getAsset?networkAssetCode=" + assetCode)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override public void onResponse(Call call, Response response) throws IOException {
                try (final ResponseBody responseBody = response.body()) {
                    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

                    Headers responseHeaders = response.headers();
                    for (int i = 0, size = responseHeaders.size(); i < size; i++) {
                        System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
                    }

                    System.out.println(responseBody.string());

                    CODE TO UPDATE jsonTextView IN UITHREAD

                }
            }
        });
    }

}

您无法从 REST class 更新其他 class UI 除非您将回调放入方法定义中。

public void getAssetUpdates(String assetCode, Callback callback) {
    ... 
    client.newCall(request).enqueue(callback);
}  

它只是围绕一些变量移动

然后,在 onClick 中定义您的回调,以便您可以在 Activity class ,

中访问您的 TextView
@Override
public void onClick(View v) {
    ... 
    r.getAssetUpdates(assetCode.getText().toString(), 
        new Callback() {
        @Override public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }

        @Override public void onResponse(Call call, Response response) throws IOException {
            try (final ResponseBody responseBody = response.body()) {
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

                ...

                // update UI in here
            } 
        }
    );
 } 

而且我确实认为 Okhttp 需要使用 runOnUiThread。


请注意,如果您有 JSON 和 REST,那么 Retrofit 将比纯 Okhttp 更好。

一个解决方案是给 REST 一个 Activity 并调用 runOnUiThread().

创建自己的侦听器并从您的 activity 传递侦听器对象..

并且 return 从 Rest 回拨给您的 Activity

第一步:创建接口

public interface MyListener
 {
 void restResult(String result);
 }

步骤 2:Implement 这个听众到你的 activity

YourActivity implements MyListener

Step 3:Pass 聆听者休息 class

Rest rest=new Rest(this);//this-- your listener object

步骤4:Modify休息构造函数

Private MyListener myListener;
 Rest(MyListener myListener){
 this.myListener=myListener;
 }

//Rest完成后传递结果

在 UITHREAD 中更新 jsonTextView 的代码

myListener.restResult(responseBody.string());

第 5 步:在您的 Activity 中得到您的结果

使用

更新文本视图
@override
restResult(String result){ 
 yourtextview.settext(result);
}