This question already has answers here:
The AsyncTask API is deprecated in Android 11. What are the alternatives?
(19 answers)
Closed 1 year ago.
I'm new to Android Java and I would really appreciate it I can get some references and/or examples to make some simple network calls without using AsyncTask.
I'm making a program to parse a simple JSON Object from a URL.
In Android 11 (API 30), All AsyncTask are going to be deprecated as shown here:
https://developer.android.com/reference/android/os/AsyncTask
This is an example of how to send a request without AsyncTask using Thread
void send_request(final String url) {
try {
Thread thread = new Thread() {
public void run() {
Looper.prepare();
final JSONObject[] maindata = {new JSONObject()};
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
String data = "";
String error_data = "";
HttpURLConnection httpURLConnection = null;
try {
httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setRequestProperty("Content-Type", "application/json");
int status = httpURLConnection.getResponseCode();
Log.d("GET RX", " status=> " + status);
try {
InputStream in = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(in);
int inputStreamData = inputStreamReader.read();
while (inputStreamData != -1) {
char current = (char) inputStreamData;
inputStreamData = inputStreamReader.read();
data += current;
}
Log.d("GET RX =>", " " + data);
sdbw sd = new sdbw(act);
maindata[0] = new JSONObject(data);
} catch (Exception exx) {
InputStream error = httpURLConnection.getErrorStream();
InputStreamReader inputStreamReader2 = new InputStreamReader(error);
int inputStreamData2 = inputStreamReader2.read();
while (inputStreamData2 != -1) {
char current = (char) inputStreamData2;
inputStreamData2 = inputStreamReader2.read();
error_data += current;
}
Log.e("TX", "error => " + error_data);
}
} catch (Exception e) {
Log.e("TX", " error => " + e.getMessage());
e.printStackTrace();
} finally {
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
handler.removeCallbacks(this);
Looper.myLooper().quit();
}
}, 2000);
Looper.loop();
}
};
thread.start();
} catch (Exception ex) {
Log.e("ERROR =>", "" + ex.getMessage());
ex.printStackTrace();
}
}
Heres what i found for room query, works well
val x = Executors.newSingleThreadExecutor().submit(Callable { mDao.getX() }).get()
Related
I am a beginner in the android studio. I will successfully connect the database but I don't know how to read a data 5 seconds once in an android studio.
I want to how to read data from the database every 5 seconds once
#Override
protected String doInBackground(String... voids) {
String result = "";
String name = voids[0];
String word = voids[1];
Log.d("myTag", "This is my test");
String connstr ="http://192.168.43.123/suruthi/login.php";
try {
URL url = new URL(connstr);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoInput(true);
http.setDoOutput(true);
OutputStream ops = http.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(ops, "UTF-8"));
String data = URLEncoder.encode("user", "UTF-8")+"="+URLEncoder.encode(name, "UTF-8")
+"&&"+ URLEncoder.encode("pass", "UTF-8")+"="+URLEncoder.encode(word, "UTF-8");
writer.write(data);
writer.flush();
writer.close();
ops.close();
InputStream ips = http.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(ips, "ISO-8859-1"));
String line ="";
while ((line = reader.readLine()) != null)
{
result += line;
}
reader.close();
ips.close();
http.disconnect();
return result;
} catch (MalformedURLException e) {
result = e.getMessage();
} catch (IOException e) {
result = e.getMessage();
}
return result;
}
}
The below timer function is working only image changes but it is not suitable for reading a database ever 5 sec once
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(5000);
runOnUiThread(new Runnable() {
#Override
public void run()
{
/* iv.setImageResource(mThumbIds[i]);
i++;
if(i >= mThumbIds.length)
{
i=0;
}*/
doInBackground();
}
});}}
catch (InterruptedException e)
{
}}};
}
I tried above the timer function to read a database but it is not working..please guide me to resolve the issues..
I am implementing a simple http server using Java ServerSocket, on Android 6.1 platform. By calling ServerSocket.accept(), the thread is blocking until request comes in.
The problem is, I always saw duplicate acceptances of the same http request, and eventually only one of them could get contents of the request. Any idea?
A simple http server using Java ServerSocket, on Android 6.1 platform
while (mServerSocket != null && !mServerSocket.isClosed()) {
try {
Log.i(TAG, "{\"msgid\":\"RunningServer\",\"msg\":\"LogHttpServer starts to listen at " + mServerSocket.getInetAddress().getHostAddress() + ":" + mServerSocket.getLocalPort() + "\"}");
Socket clientSocket = mServerSocket.accept();
Thread clientRequest = new WorkThread(clientSocket, appContext);
clientRequest.start();
} catch (Exception e) {
...
}
}
class WorkThread extends Thread {
#Override
public void run() {
Log.i(TAG, "{\"msgid\":\"ReceivingData\",\"msg\":\"LogHttpServer accepted connection from "+socket.getInetAddress().getHostAddress()+"\"}");
processHttpRequest(this.socket);
private void processHttpRequest(Socket socket) {
BufferedReader in = null;
OutputStream out = null;
if (this.socket.isConnected()) {
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
} catch (IOException e) {
Log.e(TAG, "{\"msgid\":\"IOException\",\"msg\":\"fail to get Input Stream, " + e.toString() + "\"}");
}
try {
out = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "{\"msgid\":\"IOException\",\"msg\":\"fail to get Input Stream, " + e.toString() + "\"}");
}
int lineNum = 0;
String method = null;
String request = null;
while (true) {
String line;
try {
if ( in == null || (line = in.readLine()) == null || line.length() == 0) break;
lineNum++;
Log.i(TAG, "{\"msgid\":\"HttpRequest\",\"msg\":\"" + line + "\"}");
line = line.trim();
if (lineNum == 1) {
StringTokenizer tokenized = new StringTokenizer(line);
method = tokenized.hasMoreTokens() ? tokenized.nextToken().toUpperCase() : null;
request = tokenized.hasMoreTokens() ? tokenized.nextToken().toLowerCase() : null;
}
} catch (IOException e) {
Log.e(TAG, "{\"msgid\":\"IOException\",\"msg\":\"fail to read in Stream\"}");
} catch (Exception e) {
Log.e(TAG, "{\"msgid\":\"Exception\",\"msg\":\"" + e.toString() + "\"}");
return;
}
}
...
}
}
The resulting logs show as below:
2019-06-14T10:34:52.635Z 3149 3209 I LogHttpServer: {"msgid":"RunningServer","msg":"LogHttpServer starts to listen at :::33284"}
2019-06-14T10:34:52.636Z 3149 3209 I LogHttpServer: {"msgid":"RunningServer","msg":"LogHttpServer starts to listen at :::33284"}
2019-06-14T10:34:52.636Z 3149 4409 I LogHttpServer: {"msgid":"ReceivingData","msg":"LogHttpServer accepted connection from 192.168.43.254"}
--> this is where I don't expect: duplicate acceptance with separate thread created.
2019-06-14T10:34:52.636Z 3149 4410 I LogHttpServer: {"msgid":"ReceivingData","msg":"LogHttpServer accepted connection from 192.168.43.254"}
2019-06-14T10:34:52.642Z 3149 4409 I LogHttpServer: {"msgid":"HttpRequest","Method":"GET", "Request":"/cgi-bin/logs.sh"}
--> later, it actually not able to parse the contents
2019-06-14T10:35:03.216Z 3149 4410 E LogHttpServer: {"msgid":"InvalidHttpRequest","msg":"null Method or Request. Return."}
I am writing a web server from the scratch. There I need a Http codec which can decode a string request (buffer) to an Http object and encode http object into Sting (buffer).
I found three Codecs,
Apache Codecs (can't use this because this is tightly coupled with their server coding structure)
Netty Codes (can't use this because this is tightly coupled with their server coding structure)
JDrupes Codecs (Has some concurrency issues)
But non of these can be used for my purpose. Are there any other Codecs I can use?
class SimpleHttpsServer implements Runnable {
Thread process = new Thread(this);
private static int port = 3030;
private String returnMessage;
private ServerSocket ssocket;
/************************************************************************************/
SimpleHttpsServer() {
try {
ssocket = new ServerSocket(port);
System.out.println("port " + port + " Opend");
process.start();
} catch (IOException e) {
System.out.println("port " + port + " not opened due to " + e);
System.exit(1);
}
}
/**********************************************************************************/
public void run() {
if (ssocket == null)
return;
while (true) {
Socket csocket = null;
try {
csocket = ssocket.accept();
System.out.println("New Connection accepted");
} catch (IOException e) {
System.out.println("Accept failed: " + port + ", " + e);
System.exit(1);
}
try {
DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(csocket.getInputStream()));
PrintStream printStream = new PrintStream(new BufferedOutputStream(csocket.getOutputStream(), 1024),
false);
this.returnMessage = "";
InputStream inputStream = csocket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
// code to read and print headers
String headerLine = null;
while ((headerLine = bufferedReader.readLine()).length() != 0) {
System.out.println(headerLine);
}
// code to read the post payload data
StringBuilder payload = new StringBuilder();
while (bufferedReader.ready()) {
payload.append((char) bufferedReader.read());
}
System.out.println("payload.toString().length() " + payload.toString().length());
if (payload.toString().length() != 1 || payload.toString().length() != 0) {
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(payload.toString());
// Handle here your string data and make responce
// returnMessage this can store your responce message
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String httpResponse = "HTTP/1.1 200 OK\r\n\r\n" + this.returnMessage;
printStream.write(httpResponse.getBytes("UTF-8"));
printStream.flush();
}else {
/*String httpResponse = "HTTP/1.1 200 OK\r\n\r\n";
outStream.write(httpResponse.getBytes("UTF-8"));
outStream.flush();*/
}
printStream.close();
dataInputStream.close();
// csocket.close();
System.out.println("client disconnected");
} catch (IOException e) {
e.printStackTrace();
}
}
}
/************************************************************************************/
public static void main(String[] args) {
new SimpleHttpsServer();
}
}
may be this one is help you
This is the class containing the main() method:
public class MultithreadedProxyServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
int port = 10000; //default
try {
port = Integer.parseInt(args[0]);
} catch (Exception e) {
//ignore me
System.out.println("gnore");
}
try {
serverSocket = new ServerSocket(port);
System.out.println("Started on: " + port);
} catch (IOException e) {
System.err.println("Could not listen on port: " + args[0]);
System.exit(-1);
}
while (listening) {
new ProxyThread(serverSocket.accept()).start();
}
serverSocket.close();
}
}
And this is the ProxyThread class:
public class ProxyThread extends Thread {
private Socket socket = null;
private static final int BUFFER_SIZE = 32768;
public ProxyThread(Socket socket) {
super("ProxyThread");
this.socket = socket; //initialzed my parent before you initalize me
}
public void run() {
//get input from user
//send request to server
//get response from server
//send response to user
System.out.println("run");
try {
DataOutputStream out =
new DataOutputStream(socket.getOutputStream());
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String inputLine, outputLine;
int cnt = 0;
String urlToCall = "";
///////////////////////////////////
//begin get request from client
while ((inputLine = in.readLine()) != null) {
try {
StringTokenizer tok = new StringTokenizer(inputLine);
tok.nextToken();
} catch (Exception e) {
System.out.println("break");
break;
}
//parse the first line of the request to find the url
if (cnt == 0) {
String[] tokens = inputLine.split(" ");
urlToCall = tokens[1];
//can redirect this to output log
System.out.println("Request for : " + urlToCall);
}
cnt++;
}
//end get request from client
///////////////////////////////////
BufferedReader rd = null;
try {
//System.out.println("sending request
//to real server for url: "
// + urlToCall);
///////////////////////////////////
//begin send request to server, get response from server
URL url = new URL(urlToCall);
URLConnection conn = url.openConnection();
conn.setDoInput(true);
//not doing HTTP posts
conn.setDoOutput(false);
//System.out.println("Type is: "
//+ conn.getContentType());
//System.out.println("content length: "
//+ conn.getContentLength());
//System.out.println("allowed user interaction: "
//+ conn.getAllowUserInteraction());
//System.out.println("content encoding: "
//+ conn.getContentEncoding());
//System.out.println("content type: "
//+ conn.getContentType());
// Get the response
InputStream is = null;
HttpURLConnection huc = (HttpURLConnection)conn;
if (conn.getContentLength() > 0) {
is = conn.getInputStream();
rd = new BufferedReader(new InputStreamReader(is));
}
//end send request to server, get response from server
///////////////////////////////////
///////////////////////////////////
//begin send response to client
byte by[] = new byte[ BUFFER_SIZE ];
int index = is.read( by, 0, BUFFER_SIZE );
while ( index != -1 )
{
out.write( by, 0, index );
index = is.read( by, 0, BUFFER_SIZE );
}
out.flush();
//end send response to client
///////////////////////////////////
} catch (Exception e) {
//can redirect this to error log
System.err.println("Encountered exception: " + e);
//encountered error - just send nothing back, so
//processing can continue
out.writeBytes("");
}
//close out all resources
if (rd != null) {
rd.close();
}
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have copy-pasted the above code from the internet, however I am having difficulties running it.
To answer the question from the post title, the run() method from ProxyThread class is called by JVM, after the thread has been started new ProxyThread(serverSocket.accept()).start(); and it usually contains the actual work that a thread should performed (in this case, it handles whatever the server socket receives and it accepts a connection from a client).
The moment when JVM calls run() method cannot be controlled by the programmer, but is after the thread has been started.
run() method is never called explicitly by the programmer.
We are getting some very weird behavior in Android. Our network stack (that talks to a REST server) works fine in almost all situations, except when we do a GET shortly after doing a larger POST. What appears to be happening is that the Output stream is not flushing, and ends up sending the last line that was in there when the new socket is opened. Please note, each connection is a new object created, so this is unexpected behavior. First, the error code that seems to point me to the output stream, these are from the server logs.
10.1.8.195 - - [07/Nov/2012:13:36:28 -0700] "POST /iou/lender HTTP/1.1" 200 28 "-" "Android"
10.1.8.195 - - [07/Nov/2012:13:36:36 -0700] "------------V2ymHFg03ehbqgZCaKO6jy" 400 173 "-" "-"
That attempt after should be a GET that then pulls the data from the server that includes the new entry added via the POST. However, all we get is again what appears to be the last line from the output stream from the POST. Here is our core code for the network stack, if more of the surrounding code is needed, let me know.
public Object serverConnect(String url, String method,
Hashtable<String, Object> params) {
HttpConnection c = null;
InputStream is = null;
OutputStream out = null;
ByteArrayOutputStream postDataByteArrayImage = new ByteArrayOutputStream();
byte[] data;
String boundry = "----------V2ymHFg03ehbqgZCaKO6jy";
try {
if (!url.startsWith("/")) {
url = "/" + url;
}
String uri = Control.URL_Secure + Control.dtserver + ":"
+ Control.port + url;
ByteArrayOutputStream postDataByteArray = new ByteArrayOutputStream();
params.put("sessionId", Control.sessionId);
if (method.equals("GET")) {
uri = uri + "?";
Enumeration enumParams = params.keys();
while (enumParams.hasMoreElements()) {
if (!uri.endsWith("?")) {
uri = uri + "&";
}
String key = (String) enumParams.nextElement();
uri = uri
+ key
+ "="
+ java.net.URLEncoder.encode((String) params
.get(key));
}
} else if (method.equals("POST")) {
Enumeration enumParams = params.keys();
postDataByteArray.write(("--").getBytes());
postDataByteArray.write((boundry).getBytes());
postDataByteArray.write(("\r\n").getBytes());
while (enumParams.hasMoreElements()) {
String key = (String) enumParams.nextElement();
if (!key.equals("image")){
postDataByteArray
.write(("Content-Disposition: form-data; name=\"")
.getBytes());
postDataByteArray.write((key).getBytes());
postDataByteArray.write(("\"").getBytes());
postDataByteArray.write(("\r\n\r\n").getBytes());
postDataByteArray.write(((String) params.get(key))
.getBytes());
postDataByteArray.write(("\r\n").getBytes());
postDataByteArray.write(("--").getBytes());
postDataByteArray.write(boundry.getBytes());
postDataByteArray.write(("\r\n").getBytes());
}
}
postDataByteArray.close();
}
Log.i("URL", uri);
URL urltoConenct = new URL(uri);
URLConnection connection = urltoConenct.openConnection();
HttpURLConnection urlConnection = (HttpURLConnection) connection;
URLConnection.setDefaultRequestProperty("Method", method); // default
urlConnection.setRequestProperty("User-Agent", "Android");
if (method.equals("POST")) {
urlConnection.setDoOutput(true);
urlConnection.setFixedLengthStreamingMode(postDataByteArray.toByteArray().length + postDataByteArrayImage.toByteArray().length);
urlConnection.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundry);
out = urlConnection.getOutputStream();
out.write(postDataByteArray.toByteArray());
out.write(postDataByteArrayImage.toByteArray());
out.close();
}
int response = 0;
try {
response = urlConnection.getResponseCode();
} catch (IOException e) {
if (e.toString()
.equals("java.io.IOException: Received authentication challenge is null"))
throw new RESTException(401, "Invalid Phone or Pin");
else
throw e;
}
if (response == HttpURLConnection.HTTP_OK) {
is = urlConnection.getInputStream();
if (is == null) {
return new IOException(
"Cannot open HTTP InputStream, aborting");
}
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int ch;
int count = 0;
while ((ch = is.read()) != -1) {
bo.write(ch);
count++;
}
data = bo.toByteArray();
return new String(data);
} else if (response == 500) {
return new RESTException(500, "Internal server error");
} else {
RESTException x = new RESTException();
x.setCode(response);
try {
is = urlConnection.getInputStream();
if (is == null) {
x.setMessage("Unable to retrieve message");
return x;
}
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int ch;
int count = 0;
while ((ch = is.read()) != -1) {
bo.write(ch);
count++;
}
data = bo.toByteArray();
String output = new String(data);
JSONObject obj;
try {
obj = new JSONObject(output);
JSONObject err = obj.getJSONArray("errors")
.getJSONObject(0);
x.setMessage(err.getString("message"));
} catch (JSONException e) {
Log.e("stuff", output);
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// Damn you android! I'm using a REST service here, stop
// trying to interpret my errors!
x.setMessage("Unable to retrieve message");
}
return x;
}
} catch (Exception x) {
x.printStackTrace();
/*
* if (!retried && x.toString().equals(
* "java.io.IOException: Persistent connection dropped after first chunk sent, cannot retry"
* )) { retry = true; } if (!retry) { return x; }
*/
return x;
} finally {
try {
out.close();
} catch (Exception x) {
}
try {
is.close();
} catch (Exception x) {
}
try {
c.close();
} catch (Exception x) {
}
params.clear();
}
// return null;
}
After a very long time of frustration, we discovered that Android tries to keep a connection alive even if you manually call .close() on the connection. This worked fine for our GET methods, but POST methods left the socket in a state that it couldn't then process a GET. Adding the following fixed all our problems:
urlConnection.setRequestProperty("connection", "close");