Java 如何从okhttp调用中获取数据?

Java 如何从okhttp调用中获取数据?,java,android,Java,Android,我有一个在android上使用okhttp库调用外部API的方法,我能够访问返回到该方法/线程中的数据,但我不能返回数据或在其他地方使用它。有什么问题吗 我曾尝试将数据放入另一个类(从AsyncTask扩展而来),但仍然无法工作 public class DisplayImage extends AppCompatActivity { ImageView imageView; TextView textView; @Override protected voi

我有一个在android上使用okhttp库调用外部API的方法,我能够访问返回到该方法/线程中的数据,但我不能返回数据或在其他地方使用它。有什么问题吗

我曾尝试将数据放入另一个类(从AsyncTask扩展而来),但仍然无法工作

public class DisplayImage extends AppCompatActivity {

    ImageView imageView;
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display_image);
        imageView = findViewById(R.id.mImageView);
        textView = findViewById(R.id.textView);


        Bitmap bitmap = BitmapFactory.decodeFile(getIntent().getStringExtra("image_path"));
        imageView.setImageBitmap(bitmap);

        String imagePath = getIntent().getStringExtra("image_path");

        try {
            //map returned here
            HashMap<String, double[]> map = getCropInfo(imagePath);

            //This text view doesn't update
            textView.setText(String.valueOf(map.get("ID")[0]));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    HashMap getCropInfo(String imageUri) throws Exception {
        final HashMap<String, double[]> map = new HashMap<>();

        OkHttpClient client = new OkHttpClient();

        MediaType MEDIA_TYPE_PNG = MediaType.parse("image/jpg");

        File file = new File(imageUri);

        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("image", file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file))
                .build();

        Request request = new Request.Builder()
                .header("Prediction-Key", "") //predictionkey hidden
                .header("Content-Type", "application/octet-stream")
                .url("https://westeurope.api.cognitive.microsoft.com/customvision/v3.0/Prediction/7f5583c8-36e6-4598-8fc3-f9e7db218ec7/detect/iterations/Iteration1/image")
                .post(requestBody)
                .build();

        client.newCall(request).enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            public void onResponse(Call call, final Response response) throws IOException {
                // Read data on the worker thread
                final String responseData = response.body().string();

                // Run view-related code back on the main thread
                DisplayImage.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            JSONObject jsonObject = new JSONObject(responseData);
                            JSONArray jsonArray = jsonObject.getJSONArray("predictions");
                            double highestIDProbability = 0;
                            double highestVoltageProbability = 0;

                            for (int i = 0; i < jsonArray.length(); i++) {
                                JSONObject tempObject = jsonArray.getJSONObject(i);
                                if(tempObject.getString("tagName").equals("ID") && tempObject.getDouble("probability") > highestIDProbability) {
                                    highestIDProbability = tempObject.getDouble("probability");
                                    map.put("ID", getCoordinatesPixels(tempObject));
                                }
                                else if(tempObject.getString("tagName").equals("Voltage") && tempObject.getDouble("probability") > highestVoltageProbability) {
                                    highestVoltageProbability = tempObject.getDouble("probability");
                                    map.put("Voltage", getCoordinatesPixels(tempObject));
                                }
                            }
                            //setting text view works from here.
                            //textView.setText(String.valueOf(map.get("ID")[0]));
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        });
        //I am returning map
        return map;
    }

    static double[] getCoordinatesPixels(JSONObject object) {
        double[] arr = new double[4];
        try {
            JSONObject innerObject = object.getJSONObject("boundingBox");
            arr[0] = innerObject.getDouble("left");
            arr[1] = innerObject.getDouble("top");
            arr[2] = innerObject.getDouble("width");
            arr[3] = innerObject.getDouble("height");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return arr;
    }

}
公共类DisplayImage扩展了AppCompative活动{
图像视图图像视图;
文本视图文本视图;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u display\u image);
imageView=findViewById(R.id.mImageView);
textView=findViewById(R.id.textView);
位图Bitmap=BitmapFactory.decodeFile(getIntent().getStringExtra(“图像路径”);
设置图像位图(位图);
字符串imagePath=getIntent().getStringExtra(“图像路径”);
试一试{
//地图在这里归还
HashMap map=getCropInfo(imagePath);
//此文本视图不更新
textView.setText(String.valueOf(map.get(“ID”)[0]);
}捕获(例外e){
e、 printStackTrace();
}
}
HashMap getCropInfo(字符串imageUri)引发异常{
final HashMap map=新HashMap();
OkHttpClient=新的OkHttpClient();
MediaType MEDIA_TYPE_PNG=MediaType.parse(“image/jpg”);
File File=新文件(imageUri);
RequestBody RequestBody=新的MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(“image”,file.getName(),RequestBody.create(媒体类型PNG,文件))
.build();
Request Request=newrequest.Builder()
.header(“预测键”,“”)//预测键隐藏
.header(“内容类型”、“应用程序/八位字节流”)
.url(“https://westeurope.api.cognitive.microsoft.com/customvision/v3.0/Prediction/7f5583c8-36e6-4598-8fc3-f9e7db218ec7/detect/iterations/Iteration1/image")
.post(请求主体)
.build();
client.newCall(request).enqueue(new Callback()){
@凌驾
公共void onFailure(调用调用,IOE异常){
e、 printStackTrace();
}
public void onResponse(调用、最终响应)引发IOException{
//读取工作线程上的数据
final String responseData=response.body().String();
//在主线程上运行与视图相关的代码
DisplayImage.this.runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
试一试{
JSONObject JSONObject=新的JSONObject(responseData);
JSONArray JSONArray=jsonObject.getJSONArray(“预测”);
双重高估计概率=0;
双高电压概率=0;
for(int i=0;i高估计概率){
highestIDProbability=tempObject.getDouble(“概率”);
map.put(“ID”,getCoordinateSixels(tempObject));
}
else if(tempObject.getString(“标记名”).equals(“电压”)&&tempObject.getDouble(“概率”)>highestVoltageProbability){
highestVoltageProbability=tempObject.getDouble(“概率”);
map.put(“电压”,getCoordinateSixels(tempObject));
}
}
//从这里开始设置文本视图。
//textView.setText(String.valueOf(map.get(“ID”)[0]);
}捕获(JSONException e){
e、 printStackTrace();
}
}
});
}
});
//我正在归还地图
返回图;
}
静态双[]getCoordinateSixels(JSONObject对象){
double[]arr=新的double[4];
试一试{
JSONObject innerObject=object.getJSONObject(“boundingBox”);
arr[0]=innerObject.getDouble(“左”);
arr[1]=innerObject.getDouble(“顶部”);
arr[2]=innerObject.getDouble(“宽度”);
arr[3]=innerObject.getDouble(“高度”);
}捕获(JSONException e){
e、 printStackTrace();
}
返回arr;
}
}

我需要返回映射,以便在外部使用数据。

我相信您遇到了与OkHttp和网络请求的异步性质有关的问题。当您进行新调用时,该调用将排队并异步处理。这意味着代码最有可能执行
returnmap异步调用完成之前,在回调修改映射之前。如果需要访问回调范围之外的映射,则有两个主要选项

  • 进行呼叫阻塞。这本质上意味着您必须在
    返回映射之前强制函数暂停,直到触发OkHttp回调发生。我绝对不建议这样做,因为这样做违背了将长时间运行的任务移动到其他线程的全部目的

  • onResponse()回调函数中调用函数。在回调本身内部构造
    映射
    ,然后用该映射作为参数调用函数来处理任何