从Async - Android更新UiThread上的TextView

时间:2017-02-25 18:18:57

标签: android rest okhttp3

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

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

我在我的休息班中留了一行:"代码在UITHREAD"中更新jsonTextView。在您看来,实现这一目标的最佳方法是什么?

非常感谢你,我已经浪费了很多时间。

这是我的活动

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类

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

                }
            }
        });
    }

}

3 个答案:

答案 0 :(得分:2)

除非将回调放入方法定义中,否则无法从REST类更新其他类UI。

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

它只是移动一些变量

然后,在onClick中定义您的回调,以便您可以访问该Activity类中的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。

OkHTTP Update UI from enqueue callback

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

答案 1 :(得分:0)

一种解决方案是向Activity提供REST并致电runOnUiThread()

答案 2 :(得分:0)

创建自己的监听器&amp;从您的活动传递监听器对象..

将来自Rest的回复返回到您的活动

第1步:创建界面

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

第2步:为您的活动实施此监听器

YourActivity implements MyListener

第3步:将监听器传递给Rest类

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

第4步:修改Rest构造函数

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

//完成休息后,传递结果

在UITHREAD中更新jsonTextView的代码

myListener.restResult(responseBody.string());

第5步:在您的活动中获取结果

使用

更新textview
@override
restResult(String result){ 
 yourtextview.settext(result);
}