1 Mamedov
1 Mamedov

Reputation: 26

Response error okhttp3. runOnUiThread/Thread

I want to make a request to the server and get a response from it. Next, display in displayWindow.

I can’t get a response from the server, I understand that I need to process the UI in a separate thread, I generally do this, but I don’t quite understand why I still get such an error, please tell me.

package com.openai.gpt;

import android.os.Bundle;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.io.IOException;
import java.util.Objects;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

    private static final String API_KEY = "API_KEY";
    private static final String API_URL = "API_URL";


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

        TextView displayWindow = findViewById(R.id.displayWindow);
        EditText textField = findViewById(R.id.textField);
        ImageButton sendButton = findViewById(R.id.sendButton);

        sendButton.setOnClickListener(v -> {
            String message = textField.getText().toString();
            getChatResponse(message, displayWindow);
        });
    }

    private void getChatResponse(String message, TextView displayWindow) {
        OkHttpClient client = new OkHttpClient();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create("{\"prompt\": \"" + message + "\",\"model\":\"text-davinci-003\", \"temperature\": 1, \"max_tokens\": 1000}", mediaType);
        Request request = new Request.Builder()
                .url(API_URL)
                .post(body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization", "Bearer " + API_KEY)
                .build();

        try (Response response = client.newCall(request).execute()) {
            String responseBody = Objects.requireNonNull(response.body()).string();
            JsonObject jsonObject = JsonParser.parseString(responseBody).getAsJsonObject();
            JsonArray choices = jsonObject.getAsJsonArray("choices");
            JsonObject selectedChoice = choices.get(0).getAsJsonObject();
            String text = selectedChoice.get("text").getAsString();
            runOnUiThread(() -> displayWindow.setText(text));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
Connected to the target VM, address: 'localhost:61975', transport: 'socket'
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/zygote: Late-enabling -Xcheck:jni
W/zygote: Unexpected CPU variant for X86 using defaults: x86
W/ActivityThread: Application com.openai.gpt is waiting for the debugger on port 8100...
I/System.out: Sending WAIT chunk
I/zygote: Debugger is active
I/System.out: Debugger has connected
I/System.out: waiting for debugger to settle...
I/chatty: uid=10084(u0_a84) com.openai.gpt identical 5 lines
I/System.out: waiting for debugger to settle...
I/System.out: debugger has settled (1370)
D/AppCompatDelegate: Checking for metadata for AppLocalesMetadataHolderService : Service not found
D/OpenGLRenderer: HWUI GL Pipeline
D/: HostConnection::get() New Host Connection established 0x9ba64a80, tid 28386
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
D/OpenGLRenderer: Swap behavior 0
D/EGL_emulation: eglCreateContext: 0x9bd052a0: maj 2 min 0 rcv 2
D/EGL_emulation: eglMakeCurrent: 0x9bd052a0: ver 2 0 (tinfo 0x9bd031b0)
D/EGL_emulation: eglMakeCurrent: 0x9bd052a0: ver 2 0 (tinfo 0x9bd031b0)
W/View: dispatchProvideAutofillStructure(): not laid out, ignoring
I/AssistStructure: Flattened final assist data: 1992 bytes, containing 1 windows, 8 views
I/zygote: Do partial code cache collection, code=30KB, data=23KB
I/zygote: After code cache collection, code=30KB, data=23KB
I/zygote: Increasing code cache capacity to 128KB
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
W/zygote: Got a deoptimization request on un-deoptimizable method java.net.InetAddress[] libcore.io.Linux.android_getaddrinfo(java.lang.String, android.system.StructAddrinfo, int)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.openai.gpt, PID: 28347
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1448)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:102)
        at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:90)
        at java.net.InetAddress.getAllByName(InetAddress.java:787)
        at okhttp3.Dns$Companion$DnsSystem.lookup(Dns.kt:49)
        at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.kt:164)
        at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.kt:129)
        at okhttp3.internal.connection.RouteSelector.next(RouteSelector.kt:71)
        at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:205)
        at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
        at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
        at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
        at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
        at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
        at com.openai.gpt.MainActivity.getChatResponse(MainActivity.java:56)
        at com.openai.gpt.MainActivity.lambda$onCreate$0$com-openai-gpt-MainActivity(MainActivity.java:41)
        at com.openai.gpt.MainActivity$$ExternalSyntheticLambda1.onClick(Unknown Source:6)
        at android.view.View.performClick(View.java:6256)
        at android.view.View$PerformClick.run(View.java:24701)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Disconnected from the target VM, address: 'localhost:61975', transport: 'socket'

Please tell me what am I doing wrong?

Used both runOnUiThread and Thread nothing helped

Upvotes: 1

Views: 258

Answers (1)

TG. Kahsay
TG. Kahsay

Reputation: 134

you are getting android.os.NetworkOnMainThreadException because the network call is happening on UI thread. calling runOnUiThread() from within UI thread doesn't help here. you have to first run things on a background thread and then call UI thread from the background thread.

so, may be you can try something like this.


 sendButton.setOnClickListener(v -> {
            String message = textField.getText().toString();
            Thread thread = new Thread(){
            @Override
            public void run() {
               super.run();
               getChatResponse(message, displayWindow); // call this method on a separate thread. 
               }
            };
           thread.start()
        });

P.s, there may be a better way to handle this using the okhttp library itself.

Upvotes: 0

Related Questions