How to fix android.os.NetworkOnMainThread [duplicate] - java

This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 3 years ago.
I'm getting the "android.os.NetworkOnMainThreadException" even though I'm not running anything network related in my main thread. How can I fix this?
I actually tried the code inside Eclipse and it worked just fine, but not in Android Studio where I'm developing the app itself.
Testclass.java:
package com.*****.*****;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.view.View;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.xml.xpath.*;
import javax.xml.namespace.*;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
abstract class Testclass {
public static class NamespaceResolver implements NamespaceContext {
private Document document;
public NamespaceResolver(Document doc) {
document = doc;
}
public String getNamespaceURI(String prefix) {
if (prefix.equals("")) {
return document.lookupNamespaceURI(null);
} else {
return document.lookupNamespaceURI(prefix);
}
}
public String getPrefix(String namespaceURI) {
return document.lookupPrefix(namespaceURI);
}
public Iterator<String> getPrefixes(String namespaceURI) {
return null;
}
}
public static String downloadString(String url) throws Exception {
StringBuilder sb = new StringBuilder();
try (BufferedReader r = new BufferedReader(new InputStreamReader(new URL(url).openStream(), "UTF-8"))) {
String line;
while ((line = r.readLine()) != null) {
sb.append(line + "\n");
}
}
return sb.toString();
}
public static Document createDocumentFromString(String xml) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
return factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
}
static String value;
public static String result() {
try {
String url = "http://opendata.fmi.fi/wfs/fin?service=WFS&version=2.0.0&request=GetFeature&storedquery_id=fmi::observations::mareograph::timevaluepair&fmisid=134223&";
String xml = downloadString(url);
Document document = createDocumentFromString(xml);
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new NamespaceResolver(document));
String time = xpath.evaluate("//wml2:MeasurementTimeseries[#gml:id='obs-obs-1-1-WATLEV']/wml2:point[last()]//wml2:time", document);
value = xpath.evaluate("//wml2:MeasurementTimeseries[#gml:id='obs-obs-1-1-WATLEV']/wml2:point[last()]//wml2:value", document);
System.out.format("time = %s; value = %s\n", time, value);
return value;
} catch (Exception e) {
return "FAIL: " + e.toString();
}
}
}
Output when run in android studio: "null" and also throws "android.os.NetworkOnMainThreadException"
Output when run in Eclipse: "-97.0" (correct output)

You need to run network related tasks on another thread, something like this:
Thread mThread = new Thread(new Runnable() {
#Override
public void run() {
try {
//Put your code that you want to run in here
} catch (Exception e) {
e.printStackTrace();
}
}
Now, if you are not sure what causing this you can check your error log, it will guid you to the line that caused this problem.
Another thing that you can do is to add custom logs/prints with the error description, later on, you can check those logs to see if any of them called (if yes this means that you were getting error)

You need to use Asyn Task for networking purposes.
A simple example is given in below link
Async task in android

Related

Converting serially reading multiple files to reading them in parallel? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
Following code in Java reads multiple files one after another serially and it works well till here. (The files are JSON and at this step they are stored in a String/Buffer without parsing.)
for (int fileIndex = 0; fileIndex < numberOfFiles; fileIndex++) {
BufferedReader br = new BufferedReader(new FileReader("Files/file" + fileIndex + ".json"));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String contentJSON = sb.toString();
} finally {
br.close();
}
}
How to read those files in parallel by using Threads ?
I could not match Multithreading to above code and every time got errors.
I've not tested this code directly (as I don't have a bunch of files to read), but the basic idea would be to do something like...
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
try {
int numberOfFiles = 10;
ExecutorService service = Executors.newFixedThreadPool(10);
List<ReadWorker> workers = new ArrayList<>(numberOfFiles);
for (int fileIndex = 0; fileIndex < numberOfFiles; fileIndex++) {
workers.add(new ReadWorker(fileIndex));
}
List<Future<String>> results = service.invokeAll(workers);
for (Future<String> result : results) {
try {
String value = result.get();
} catch (ExecutionException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
public class ReadWorker implements Callable<String> {
private int fileIndex;
public ReadWorker(int fileIndex) {
this.fileIndex = fileIndex;
}
#Override
public String call() throws Exception {
try (BufferedReader br = new BufferedReader(new FileReader("Files/file" + fileIndex + ".json"))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
return sb.toString();
}
}
}
}
This will basically execute a series of Callables and wait for them all to complete, at which time, you can then read the results (or errors)
See the Executors trail for more details
Tested and verified version...
So, I dumped a series of files into a the Files folder at the root of my working directory, modified the above example to list all the files in that directory and read them....
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
File files[] = new File("Files").listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return pathname.getName().toLowerCase().endsWith(".svg");
}
});
try {
int numberOfFiles = files.length;
ExecutorService service = Executors.newFixedThreadPool(20);
List<ReadWorker> workers = new ArrayList<>(numberOfFiles);
for (File file : files) {
workers.add(new ReadWorker(file));
}
System.out.println("Execute...");
List<Future<String>> results = service.invokeAll(workers);
System.out.println("Results...");
for (Future<String> result : results) {
try {
String value = result.get();
System.out.println(value);
} catch (ExecutionException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
service.shutdownNow();
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
public class ReadWorker implements Callable<String> {
private File file;
public ReadWorker(File file) {
this.file = file;
}
#Override
public String call() throws Exception {
System.out.println("Reading " + file);
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
return sb.toString();
}
}
}
}
And this works just fine and I have no issue.
java.io.FileNotFoundException: Files\file0.json is a localised issue you are going to have to solve. Does file0.json actually exist? Does it exist in the Files directory? Is the Files directory in the root of the working directory when the program is executed?
None of these issues can be solved by us, as we don't have access to your environment
Test #3
I then renamed all the files in my Files directory to file{x}.json using...
File files[] = new File("Files").listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return pathname.getName().toLowerCase().endsWith(".svg");
}
});
for (int index = 0; index < files.length; index++) {
File source = files[index];
File target = new File(source.getParent(), "file" + index + ".json");
source.renameTo(target);
}
And the modified the example slightly to include a File#exists report...
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
try {
int numberOfFiles = 10;
ExecutorService service = Executors.newFixedThreadPool(20);
List<ReadWorker> workers = new ArrayList<>(numberOfFiles);
for (int index = 0; index < numberOfFiles; index++) {
workers.add(new ReadWorker(index));
}
System.out.println("Execute...");
List<Future<String>> results = service.invokeAll(workers);
System.out.println("Results...");
for (Future<String> result : results) {
try {
String value = result.get();
System.out.println(value);
} catch (ExecutionException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
service.shutdownNow();
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
public class ReadWorker implements Callable<String> {
private int fileIndex;
public ReadWorker(int fileIndex) {
this.fileIndex = fileIndex;
}
#Override
public String call() throws Exception {
System.out.println("Reading " + fileIndex);
File file = new File("Files/file" + fileIndex + ".json");
System.out.println("File " + fileIndex + " exists = " + file.exists());
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
return sb.toString();
} finally {
System.out.println("All done here");
}
}
}
}
Which prints
Execute...
Reading 8
Reading 1
Reading 2
Reading 4
Reading 6
Reading 9
Reading 3
Reading 7
Reading 0
Reading 5
File 8 exists = true
File 1 exists = true
File 5 exists = true
File 4 exists = true
File 9 exists = true
File 2 exists = true
File 0 exists = true
File 3 exists = true
File 7 exists = true
File 6 exists = true
All done here
All done here
All done here
All done here
All done here
All done here
All done here
All done here
All done here
All done here
Results...
// I won't bore you with the results, as it's a lot of pointless text
which all worked without issues

"android.os.NetworkOnMainThreadException" even when running in AsyncTask

I'm getting the android.os.NetworkOnMainThreadException error even when I'm running the code inside AsyncTask thread. This is basically just a chunk of code that should return me a value from a website.
package com.jasperhonkasalo.merenpinnankorkeusvsa;
import android.os.AsyncTask;
import android.util.Log;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import java.util.Iterator;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
public class NewBackgroundTask {
public static class BackgroundTask extends AsyncTask<String, Void, String> {
String value = "presetvalue";
#Override
protected String doInBackground(String... urls) {
class NamespaceResolver implements NamespaceContext {
private Document document;
public NamespaceResolver(Document doc) {
document = doc;
}
public String getNamespaceURI(String prefix) {
if (prefix.equals("")) {
return document.lookupNamespaceURI(null);
} else {
return document.lookupNamespaceURI(prefix);
}
}
public String getPrefix(String namespaceURI) {
return document.lookupPrefix(namespaceURI);
}
public Iterator<String> getPrefixes(String namespaceURI) {
return null;
}
}
try {
String url = "http://opendata.fmi.fi/wfs/fin?service=WFS&version=2.0.0&request=GetFeature&storedquery_id=fmi::observations::mareograph::timevaluepair&fmisid=134223&";
StringBuilder sb = new StringBuilder();
try (BufferedReader r = new BufferedReader(new InputStreamReader(new URL(url).openStream(), "UTF-8"))) {
String line;
while ((line = r.readLine()) != null) {
sb.append(line + "\n");
}
}
String xml = sb.toString();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document document = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new NamespaceResolver(document));
String time = xpath.evaluate("//wml2:MeasurementTimeseries[#gml:id='obs-obs-1-1-WATLEV']/wml2:point[last()]//wml2:time", document);
value = xpath.evaluate("//wml2:MeasurementTimeseries[#gml:id='obs-obs-1-1-WATLEV']/wml2:point[last()]//wml2:value", document);
System.out.format("time = %s; value = %s\n", time, value);
return value;
} catch (Exception e) {
Log.d("EXCEPTIONFAIL", e.toString());
return "FAIL: " + e.toString();
}
}
#Override
protected void onPostExecute(String feed) {
// TODO: do something with the feed
}
}
}
I'm getting the value with:
static String eeee = new NewBackgroundTask.BackgroundTask().value;
The value of "value"- variable is staying the same (presetvalue) and also giving me a android.os.NetworkOnMainThreadException error. I'm really new to any java programming and would appreciate any help.
You need to execute the AsyncTask, you cannot simply access a static field of it and expect it to give you any result. You need to do something like that:
new BackgroundTask().execute();
Since this is an asynchronous call, it cannot return a result directly (that's what asynchronous means). Instead, you get the result in the onPostExecute() method, which is executed in the main thread.
If you are really completely new to Java programming, you should perhaps not start with asynchronous method calls. That's something, even experienced developers have sometimes problems with.

Search for a string in html file using Jsoup

Can anyone help me with searching for a particular string in HTML file using Jsoup or any other method. There are inbuilt methods but they help in extracting title or script texts inside a specific tags and not string in general.
In this code I have used one such inbuilt method to extract title from the html page.
But I want to search a string instead.
package dynamic_tester;
import java.io.File;
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
public class tester {
public static void main(String args[])
{
Document htmlFile = null;
{
try {
htmlFile = Jsoup.parse(new File("x.html"), "ISO-8859-1");
}
catch (IOException e)
{
e.printStackTrace();
}
String title = htmlFile.title();
System.out.println("Title = "+title);
}
}
}
Here's a sample. It reads the HTML file as text String and then performs search on that String.
package com.example;
import java.io.FileInputStream;
import java.nio.charset.Charset;
public class SearchTest {
public static void main(String[] args) throws Exception {
StringBuffer htmlStr = getStringFromFile("test.html", "ISO-8859-1");
boolean isPresent = htmlStr.indexOf("hello") != -1;
System.out.println("is Present ? : " + isPresent);
}
private static StringBuffer getStringFromFile(String fileName, String charSetOfFile) {
StringBuffer strBuffer = new StringBuffer();
try(FileInputStream fis = new FileInputStream(fileName)) {
byte[] buffer = new byte[10240]; //10K buffer;
int readLen = -1;
while( (readLen = fis.read(buffer)) != -1) {
strBuffer.append( new String(buffer, 0, readLen, Charset.forName(charSetOfFile)));
}
} catch(Exception ex) {
ex.printStackTrace();
strBuffer = new StringBuffer();
}
return strBuffer;
}
}

wants to execute a java class(which contains main) dynamically from a struts2 web page

I wanted to create a web page in Struts2.0 which contains a textarea, a property field and submit button. User will enter a java code in this text area and my code will compile it and execute it and will give the result of this code on my property field... the above code works fine in a standalone application. but it does not shows any thing in my web application. plz any one can address it... thanks in advance.
package org.controller;
import com.opensymphony.xwork2.ActionSupport;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
public class JCompilerAction extends ActionSupport
{
String program;
String MSg;
public JCompilerAction() {
}
public String getProgram() {
return program;
}
public void setProgram(String program) {
this.program = program;
}
public String getMSg() {
return MSg;
}
public void setMSg(String MSg) {
this.MSg = MSg;
}
public String Compile() {
try {
byte[] bFile = program.getBytes();
File f = new File("D:/nullprog.java");
FileOutputStream fileOuputStream = new FileOutputStream(f);
fileOuputStream.write(bFile);
fileOuputStream.close();
Process p1 = Runtime.getRuntime().exec("javac D:/nullprog.java");
BufferedReader in = new BufferedReader(new InputStreamReader(p1.getErrorStream()));
String line = null;
boolean isError = false;
while ((line = in.readLine()) != null) {
MSg = line;
isError = true;
return SUCCESS;
}
p1.waitFor();
if (!isError)
{
Process p2 = Runtime.getRuntime().exec("cmd /c start nullprog");
BufferedReader in1 = new BufferedReader(new InputStreamReader(p2.getInputStream()));
String line1 = null;
while ((line1 = in1.readLine()) != null) {
MSg += line1;
}
return SUCCESS;
}
} catch (Exception e) {
e.printStackTrace();
}
return SUCCESS;
}
public String execute() {
return SUCCESS;
}
}
Below is a simple program that first compiles a code and then executes it:
Executer.java
import java.lang.reflect.Method;
public class Executer {
public static void main(String args[]) {
try{
java.lang.Process p1 = Runtime.getRuntime().exec("javac MyClass.java");
p1.waitFor();
Class<?> c = Class.forName("MyClass");
Object obj = c.newInstance();
Method[] mArr = obj.getClass().getMethods();
for(Method m : mArr){
if(m.getName().equalsIgnoreCase("main")){
m.invoke(obj, new Object[]{new String[]{}});
}
}
} catch (Exception e){
e.printStackTrace();
}
}
}
MyClass.java
import javax.swing.JOptionPane;
public class MyClass {
public static void main(String[] args) {
JOptionPane.showMessageDialog(null, "Hii");
}
}
For simplicity both the classes are in same package. When I execute Executer class, it first compiles MyClass.java and then runs the main method.
If your requirement is to have the Java files in some folder outside of the project, the to load the compiler class file, you need to follow as mentioned in this answer.

How do I get the RFT version number?

How can a Rational Functional Tester script figure out under which version of RFT it executes/was built with?
I digged through the documentation, and the closest I found was
com.rational.test.ft.script.ScriptUtilities.getOperatingSystemVersion()
which returns OS version info, which might be close, but still not what Daddy is looking for ;O
I didn't find anything in the APIs or in the Windows registry.
The only way I can think of is to create a custom method and include it in you helper class.
You can find the versione in the file C:\IBM\SDP\FunctionalTester\properties\version\IBM_Rational_Functional_Tester.*.*.swtag, change the path to match your installation.
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
private final static String RFTVersionFolder = "C:\\IBM\\SDP\\FunctionalTester\\properties\\version";
public static String getRFTVersionWithXML() {
File versionFolder = new File(RFTVersionFolder);
File[] versionFile = versionFolder.listFiles( new FilenameFilter() {
public boolean accept(File dir, String name) {
return (name.endsWith(".swtag"));
} } );
Document versionDocument = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
versionDocument = builder.parse(new FileInputStream(versionFile[0]));
} catch (SAXParseException spe) {
spe.printStackTrace();
} catch (SAXException sxe) {
sxe.printStackTrace();
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
Node versionNode = versionDocument.getElementsByTagName("ProductVersion").item(0);
return versionNode.getTextContent();
}
This is a quite expensive method, because it istantiates a DocumentBuilder for XML parsing.
As an alternative, load the file content as a String and parse it with a RegExp,
use this matching pattern: [0-9]\.[0-9]\.[0-9]
public static String getRFTVersionWithRegexp() {
File versionFolder = new File(RFTVersionFolder);
File[] versionFile = versionFolder.listFiles( new FilenameFilter() {
public boolean accept(File dir, String name) {
return (name.endsWith(".swtag"));
} } );
byte[] buffer = null;
FileInputStream fin;
try {
fin = new FileInputStream(versionFile[0]);
buffer = new byte[(int) versionFile[0].length()];
new DataInputStream(fin).readFully(buffer);
fin.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
String versionFileContent = new String(buffer);
String version = null;
Regex r = new Regex("[0-9]\\.[0-9]\\.[0-9]", Regex.MATCH_NORMAL);
if (r.matches(versionFileContent))
version = r.getMatch();
return version;
}
1) Go to Help> About RFT, it shows the version.

Categories

Resources