This question already has answers here:
How to avoid the ANR dialog Application Not Responding
(3 answers)
Closed 5 years ago.
I'm using the method below to extract to convert XML into JSON.!
First I a pass the url for the api call of the xml and then extract
the data and put it in String.
Then using this Library, I
convert the xml into JSON Object.
Finally I use the json object data
to get web data and populate my recyclerviews.
It works well, but sometimes it gives me ANR dialog..! any help?
public static void getResponse(final String xmlLink, final Activity activity,
final GetJSONRespone getjson) {
Handler uiHandler = new Handler(Looper.getMainLooper());
uiHandler.post(new Runnable() {
#Override
public void run() {
URL url = null;
BufferedReader in = null;
try {
url = new URL(xmlLink);
in = new BufferedReader(
new InputStreamReader(
url.openStream(), "UTF-8"));
String inputLine;
System.setProperty("http.keepAlive", "false");
StringBuilder builder = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
builder.append(inputLine);
}
String urlContent = builder.toString();
XmlToJson xmlToJson = new XmlToJson.Builder(urlContent).build();
JSONObject response = xmlToJson.toJson();
Log.i("response: ", response.toString());
getjson.getJSON(response);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
}
This dialog appears when main thread of the application blocked for too long. So try to use ASYNCTASK to avoid this halt.
Related
I'm hosting a http webserver in java(just localhost) to show an offline website(plain html). To send data back to java, a save button does a call with post/ form data using ajax.
I'm using com.sun.net.httpserver.HttpServer;
and would like to just being able to obtain the xml string in the handler.
I've tried several mapping functions, and examples found online. none which helped. They all found empty results so far.
My goal is to just select the xml variable, other variables do not matter. ( no iterative search / parser is required)
thanks in advance!
Erik
Javascript code:
<script type ="text/javascript">
function saveFile() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText);
}
};
xhttp.open("POST", "/", true);
//xhttp.setRequestHeader("Accept", "text");
xhttp.setRequestHeader("content-type", "multipart/form-data");
formData.append('xml', '<xml>some xml thing here</xml>');
xhttp.send(formData);
}
</script>
java handler code:
private static void handleRequest(HttpExchange exchange) throws IOException {
String root = "TestPlanDesigner";
URI uri = exchange.getRequestURI();
//System.out.println(uri);
//printRequestInfo(exchange);
//if its the root, this means its posting the data
if(uri.getPath().equals("/"))
{
if(exchange.getRequestMethod().equals("POST"))
{
//handle the post request.
String response = "File saved successfully";
exchange.sendResponseHeaders(200, response.getBytes().length);
OutputStream os = exchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
Single line to select the xml form data in java, inside the handler.
Found it, it was in the body not the header.
in the handler:
String payloadrequest = getStringFromInputStream(exchange.getRequestBody());
private static String getStringFromInputStream(java.io.InputStream inputStream) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(inputStream));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
I wrote a program that fetches data from the Internet.
public class GetDataService {
public List<String> getData() {
List<String> lines = new ArrayList<>();
try {
URL url = new URL("http://worldtimeapi.org/api/ip.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
String a = line;
lines.add(a);
}
bufferedReader.close();
} catch (IOException ex) {
throw new RuntimeException("Can not making the request to the URL.");
}
return lines;
}
}
Now I want to test network error by using Mockito. How can I do it? Also, is my code good? Any suggestions to improve it?
You can do it this way :
when(mockUsingNetwork.doSomeNetworkAction()).thenReturn(new SomeNetworkError());
SomeNetworkError such as ConnectException for sockets for example
for your case it will be some thing like :
URL url = Mockito.mock(URL.class);
when(url.openConnection()).thenThrow(new IOException());
I wanna convert xml data from URL to json using this library , but it doesn't handle xml from URLs..! only if it was a string or file, so I wanna convert the data inside the url into a string!
is it possible?
This fragment can help you
new Thread() {
public void run() {
URL url = null;
BufferedReader in = null;
try {
url = new URL("your url");
in = new BufferedReader(
new InputStreamReader(
url.openStream(),"UTF-8"));//in most cases there is utf 8
String inputLine;
StringBuilder builder = new StringBuilder();
while ((inputLine = in.readLine()) != null)
builder.append(inputLine);
String urlContent = builder.toString();
// process your received data somehow
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}.start();
I'm creating an app where I need a function to get plain text from a website. I am able to get the text and print it out on my PC just fine, but when I try running it on an Android device, the app won't start.
I believe it has something to do with throwing an IOException. I've been reading that I am not supposed to do that because I don't define the interface. Is there a way to get around this? Android Studio won't compile my code if I don't throw the exception.
The function:
public String getText(String site) throws IOException {
// Make a URL to the web page
URL url = new URL(site);
// Get the input stream through URL Connection
URLConnection con = url.openConnection();
InputStream is =con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// read each line and return the final text
String res = "";
String line = null;
while ((line = br.readLine()) != null) {
//System.out.println(line);
res += line;
}
return res;
}
And this is how Android Studio makes me run it in the onCreate method:
String text = null;
try {
text = getText("http://myWebsite.com");
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show();
First, read your logcat - you should see your exception there with full stacktrace. Second, there is nothing wrong with catching IOException, but you must do something with it once cached - like inform user of problem in functionality - like no more space, etc.
And this is how Android Studio makes me run it in the onCreate method:
this is a problem, because your are getting data from your site on UI thread, you must do it from worker thread, ie. AsyncTask.
You can not do it in the main thread
try this
class MyTask extends AsyncTask<Void, Void, String>{
private String site;
MyTask(String site) {
this.site = site;
}
#Override
protected String doInBackground(Void... params) {
try {
URL url = new URL(site);
URLConnection con = url.openConnection();
InputStream is =con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// read each line and return the final text
String res = "";
String line = null;
while ((line = br.readLine()) != null) {
//System.out.println(line);
res += line;
}
return res;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if(s != null){
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
}
}
}
where to get a string is used as
new MyTask("http://myWebsite.com").execute()
I am trying to get a String of http response (just a JSON object), and sometimes this piece of code waits infinite time in
line = reader.readLine()
May be, the reason of such behavior is bad Internet connection (I use 3G modem), but I need a stable solution to avoid this infinite lock. What can be done here to avoid it?
HttpResponse response = httpClient.execute(httpPost);
InputStream content = null;
JSONObject json_obj;
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
try {
content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content, "UTF-8"), 256);
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {}
}
You can specify a read timeout:
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 30000);
Should set a read timeout to 30 seconds.
Probably, you also want to specify a connection timeout:
client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30000);
readLine()
Or any network/IO should be done in a background thread to prevent locking of the main thread.
If you test your code on Android 4.0+ you'll also see that networking is no longer allowed on the main thread and will throw an exception.
Take a look at AsyncTask which is a simple, painless way of running such tasks on a background thread.
A good solution to avoid the "infinite" lock is to do this http calls in a separate thread, and with a Handler, notice to the main thread that the info is loaded and can use it like you want.
Here an example of my own using a SaxParser too:
public void SearchFromSuperClass(String text)
{
mHandler = new Handler();
Thread t = new Thread(){
public void run() {
try {
String strurl="URLTOPATH";
URL url = new URL(strurl);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
FundsHandlerRanking handler = new FundsHandlerRanking();
parser.parse(url.openConnection().getInputStream(), handler);
search_response = handler.getrankings();
mHandler.post(mUpdateResults);
} catch (Exception e) {
search_response = null;
mHandler.post(mUpdateResults);
}
}
};
t.start();
}
final Runnable mUpdateResults = new Runnable() {
public void run() {
updateResultsInUi();
}
};
private void updateResultsInUi() {
try
{
if(search_response != null)
{
lview.setAdapter(new SearchRankingAdapter(mycontext, search_response, false));
}
Pdialog.dismiss();
}
catch (Exception e) {
lview.setAdapter(null);
if (Pdialog.isShowing())
{
Pdialog.dismiss();
}
}
}
With mHandler.post(...) you put the call in the queue to be sended to the main UI thread, and there, you can modify UI objects without problem (CAN'T modify UI objects outside the Main thread).
Hope this helps