Android app crash after trying to launch a HttpURLConnection function - android

I'm trying to create a connection to a servlet and send a Json File, here is the part of the code where the app crashes:
findViewById(R.id.main_login_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finalJson=createJfile();
try {
HTTPConnection(finalJson);
} catch (IOException e) {
e.printStackTrace();
}
}
});
The function is the following one:
public void HTTPConnection(String Json) throws IOException{
URL url;
url = new URL("http://192.168.0.136:8080/ProgettoProva/AndroidApp");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setRequestProperty("Accept", "text/json");
OutputStreamWriter writer =new OutputStreamWriter(conn.getOutputStream());
writer.write(Json);
writer.close();
conn.disconnect();
}
In the LogCat, nothing is showed. The app just crashed when it starts the function.

You should execute network code in a AsyncTask. Android does not allow Networking in the main Thread.
private class MyAsyncTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
//Do network code here
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
Execute with
new LongOperation().execute();

Related

android retrieve data in class with asynctask extended

hello im using Android Studio an im trying to retrieve a json from a class with asynctask but i can retrieve the data obtained to the main thread if if create a getter to obtaind data variable it's null and i get an error in runtime can you help me please?
this is the code:
(mainactivity)
Tarea tarea= new Tarea(URL_DATA,Request.toString(),this);
tarea.execute();
texto.setText((CharSequence) tarea.getData());
(class)
public class Tarea extends AsyncTask {
ProgressDialog progressDialog;
String MyURL,MJson;
volatile String data="";
public String getData() {
return data;
}
public Tarea(String myURL, String mJson, Context contexto) {
this.contexto = contexto;
this.MJson=mJson;
this.MyURL=myURL;
}
Context contexto;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog=new ProgressDialog(contexto);
progressDialog.setMessage("Buscando Paqueterias, por favor espera un momento...");
progressDialog.show();
}
#Override
protected Object doInBackground(Object[] objects) {
if(MyURL!=null&&MJson!=null) {
try {
URL url = new URL(MyURL.toString());
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
conn.setDoInput(true);
JSONObject MyJson = new JSONObject(MJson);
DataOutputStream os = new DataOutputStream(conn.getOutputStream());
os.writeBytes(MyJson.toString());
os.flush();
os.close();
//Log.i("Status",String.valueOf(conn.getResponseCode()));
//Log.i("MSG", conn.getResponseMessage());
InputStream in = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(in);
int inputStreamData = inputStreamReader.read();
while (inputStreamData != -1) {
char current = (char) inputStreamData;
inputStreamData = inputStreamReader.read();
data += current;
}
} catch (Exception e) {
e.printStackTrace();
}
progressDialog.dismiss();
}else {
Log.i("Error...","Alguna de las variables MyURL o MJson esta vacia...");
}
return data;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("REs",data);
}
}
i can print the LOG but i cant send it to the mainactivity to manupulate the json
You can do this with the help of callback approach.
Steps
1. Create an interface
2. Create an inner class on activity implement that interface.
3. Pass the instance of inner class to "Tarea" constructor.
4. Use constructor variable to communicate with activity.
You can also do the with different approach by overriding onPostExecute.
Use below code..
Tarea tarea= new Tarea(URL_DATA,Request.toString(),this) {
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
};

Spying an AsyncTask doesn't work

I am testing an AsyncTask. I want to stub an HttpURLConnection to return my mocked object. This is how I do it (PackageDownloader represents an AsyncTask):
...
PackageDownloader packageDownloader = new PackageDownloader();
packageDownloader.setParameters(URL, downloadFolder, downloadProgressCallback);
PackageDownloader mPackageDownloader = spy(packageDownloader);
HttpURLConnection connectionMock = Mockito.mock(HttpURLConnection.class);
doReturn(0).when(connectionMock).getContentLength();
doReturn(connectionMock).when(mPackageDownloader).createConnection(Mockito.any(URL.class));
mPackageDownloader.execute();
mPackageDownloader.get();
This is PackageDownloader:
public HttpURLConnection createConnection(URL url) throws IOException {
HttpURLConnection connection;
connection = (HttpURLConnection) url.openConnection();
return connection;
}
#Override
protected DownloadResult doInBackground(Void... params) {
HttpURLConnection connection;
URL downloadUrl = new URL(downloadUrlString);
connection = createConnection(downloadUrl);
long totalBytes = connection.getContentLength();
...
Here, createConnection returns real, not mocked object, and I can't figure out why.
Well I have found a solution, though haven't found an explanation why it works so.
The reason nothing worked was that doInBackground method is async, I assume, so I had to call it directly via reflection, like so:
Method method = mPackageDownloader.getClass().getMethod("doInBackground", Void[].class);
method.invoke(mPackageDownloader, new Void[] {null});
You can use robolectric to test the asynctask rather than reflection. Following the ShadowApplication.runBackgroundTasks() should invoke the doInBackground() method.
#RunWith(RobolectricTestRunner.class)
public class AcknowledgeAppRemovedTaskTest {
#Test
public void execute_shouldOpenInputStreamOfConnection() throws IOException {
DownloadTask spy = spy(new DownloadTask());
HttpURLConnection connectionMock = mock(HttpURLConnection.class);
doReturn(connectionMock).when(spy).createConnection(any(URL.class));
spy.execute();
ShadowApplication.runBackgroundTasks();
verify(connectionMock).getInputStream();
}
}
class DownloadTask extends AsyncTask<Void, Void, Void> {}
public HttpURLConnection createConnection(URL url) throws IOException {
return (HttpURLConnection) url.openConnection();
}
#Override
protected Void doInBackground(Void... voids) {
try {
HttpURLConnection urlConnection = createConnection(new URL("https://www.google.com/"));
urlConnection.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
https://github.com/robolectric/robolectric/blob/master/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskTest.java
https://groups.google.com/forum/#!topic/mockito/mqF21aqTi5g

Async HttpRequest Timing Out

The Problem
I have an AsyncTask task called from an Activity's OnCreate method. This task makes an http request. The HTTP request hangs. Once the "CODE HANGS HERE" code in the code below is executed, I observe in the debugger that the Async threads are perpetually 'running' and never return anything.
The Code
Here's the OnCreate method of the activity:
protected void onCreate(Bundle savedInstanceState) {
asyncRequest.delegate = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activty_attach);
Button retakeButton = (Button) (findViewById(R.id.retake_button));
retakeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(AttachActivity.this, MainActivity.class);
startActivity(intent);
}
});
try {
URL url;
url = new URL("http://btl-cromwell:9000/api/engine/v1/version");
asyncRequest.execute(url);
} catch (Exception e) {
Log.e(logtag, e.toString());
}
}
Note the URL that is passed to he async task should just return JSON containing the version number of the service receiving the request.
The async task (asyncRequest) code is below:
public class AsyncRequest extends AsyncTask<URL, Void, List<String>> {
private String logtag = "AsyncRequestTask";
public AsyncResponse delegate;
List<String> projects = new ArrayList<String>();
#Override
protected void onPreExecute(){
super.onPreExecute();
}
#Override
protected List<String> doInBackground(URL... urls) {
try {
// Creating & connection Connection with url and required Header.
HttpURLConnection urlConnection = (HttpURLConnection) urls[0].openConnection();
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestMethod("GET"); //POST or GET
urlConnection.setRequestProperty("User-Agent", "Test");
// CODE HANGS HERE
int responseCode = urlConnection.getResponseCode();
String responseMessage = urlConnection.getResponseMessage();
projects.add(responseMessage);
} catch (Exception e) {
Log.e(logtag, e.toString());
}
return projects;
}
#Override
protected void onPostExecute(List<String> result){
delegate.processFinish(result);
}
}
Once I have the request working I will populate the projects variable with what I actually want to return but for now I just have it set to responseMessage. I'm sure this is just something to do with my unfamiliarity in making requests in Java, but I have spent days on this and can't figure it out. Any help is greatly appreciated.
asyncRequest.execute(url);
asyncRequest.getStatus();
String[] projects = asyncRequest.get();
It is not possible to do both an .execute and a .get().
As you should never use .get(), you better remove that statement.
Remove all code after asyncRequest.execute(url); and put that code in the onPostExecute of your AsyncTask.

android connect to nodejs

I have pc running node in the same wifi with development phone(i dont use virtual device).
I test nodejs server with firefox extension rested and works fine(same pc with server)
I try to post from my android app a simple json. No error thrown but no seems to work(I have a console.log() on server's .post which not shown). I have also open 8080 port. here is my android code
public void sendJson(View view) {
new LongOperation().execute();
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
URL url = new URL("http://192.168.1.5:8080/api");
URLConnection urlConn;
DataInputStream input;
urlConn = url.openConnection();
urlConn.setDoInput (true);
urlConn.setDoOutput (true);
urlConn.setUseCaches (false);
urlConn.setRequestProperty("Content-Type","application/json");
urlConn.setRequestProperty("Host", "android.schoolportal.gr");
urlConn.connect();
//Create JSONObject here
JSONObject jsonParam = new JSONObject();
jsonParam.put("name", "kalosto");
// Send POST output.
OutputStreamWriter printout = new OutputStreamWriter(urlConn.getOutputStream ());
printout.write(jsonParam.toString());
printout.flush ();
printout.close ();
} catch (Exception e) {
e.printStackTrace();
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
I change the request from post to get, from my phone browser i can access the server and the console.log be triggered but app still do nothing

Trouble in calculating the size of URL

I want to know the size of the url in order to download the file but its crashing on runtime. Here is my code:
public class MainActivity extends AppCompatActivity {
TextView t1;
private int i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t1=(TextView)findViewById(R.id.text1);
try {
URL url = new URL("https://www.planwallpaper.com/static/images/beautiful-sunset-images-196063.jpg");
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
i = conection.getContentLength();
}
catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
t1.setText(i + "MB");
}
}
all url task done in background,so use Async Task class for this........
Below code ......look like this
class SignInAsyntask extends AsyncTask<String, String, String> {
String result;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... strings) {
// doing all url works.................
return result;
}
#Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
Log.e("Result", response);
}
}
and call it onCreate() method look like tis......
new SignInAsyncTask().execute();
The reason your app crashes is because you're accessing the network on the main thread. You should make the network call on a background thread, using AsyncTask.

Categories

Resources