Reputation: 26
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
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