I did this code to change the tabs name from HTML but i got this error :
android.os.NetworkOnMainThreadException
android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork
I know you can't do networks operations on the main thread but here i use runOnUiThread so it should be this error.
Thread thread = new Thread()
{
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run()
{
try
{
Document doc = Jsoup.connect("http://terry.gonguet.com/cal/?g=tp11").get();
Elements days = doc.select("div.day");
for (Element day : days)
{
String jour = day.getElementsByClass("dayDate").first().html();
mSectionsPagerAdapter.AddFragment(new MainFragment().newInstance(1), jour);
}
}catch (IOException ex){}
}
});
}
};
thread.start();
I know you can't do networks operations on the main thread
You clearly are doing network operation in the main thread since runOnUiThread will run on the main thread and you are calling Jsoup.connect which is a network connection.
You need to either create an AsyncTask which is preferable than a Thread; unless you are doing a long running task.
You can not run network operations on the UI thread because your interface will freeze until the finish of network operatin, you can use AsyncTask for this, it is the perfect solution for this kind of operations. With AsyncTask you can run a network operation and update the UI after (and even during) the network operation. For example:
new AsyncTask<String, String, Elements>(){
#Override
protected Elements doInBackground(String... params) {
Document doc = Jsoup.connect("http://terry.gonguet.com/cal/?g=tp11").get();
Elements days = doc.select("div.day");
return days;
}
#Override
protected void onPostExecute(Elements days) {
for (Element day : days) {
String jour = day.getElementsByClass("dayDate").first().html();
mSectionsPagerAdapter.AddFragment(new MainFragment().newInstance(1), jour);
}
}
}.execute();
You should only add the fragments inside the UI thread but not the request so this should work:
Thread thread = new Thread() {
#Override
public void run() {
try
{
Document doc = Jsoup.connect("http://terry.gonguet.com/cal/?g=tp11").get();
Elements days = doc.select("div.day");
runOnUiThread(new Runnable() {
#Override
public void run()
{
for (Element day : days)
{
String jour = day.getElementsByClass("dayDate").first().html();
mSectionsPagerAdapter.AddFragment(new MainFragment().newInstance(1), jour);
}
}
});
} catch (IOException ex){}
}
};
thread.start();
Related
In my react-native JS code I'm calling a Native Module and it was blocking the UI thread for about 1.5sec. Running it on a different thread with a Runnable works but I can't capture the returned value that happens inside the Runnable?
#ReactMethod
public void print(final String printerAddress, final String price, final String description, final String upc, Promise promise) {
try {
boolean success = false;
new Thread(new Runnable() {
public void run() {
success = mEpsonPrinter.printLabel(printerAddress, price, description, upc);
}
}).start();
promise.resolve(success);
} catch (IllegalViewOperationException e) {
promise.reject(e);
}
}
To resolve the immediate problem I placed the promise.resolve(success) call inside the Runnable.run()
try {
new Thread(new Runnable() {
public void run() {
boolean success = mEpsonPrinter.printLabel(printerAddress, price, description, upc);
promise.resolve(success);
}
}).start();
} catch (IllegalViewOperationException e) {
promise.reject(e);
}
Although I'm still left with questioning a solution for callback pattern with Java.
I am using handler to get GCM value
I want to update this value in my database
so I call AsyncTask from the handler
but I get this Error
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
I checked other solutions they said I have to put the code in the run() section which I already do..
This is the code,
private void GetGCM(final String UserID) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
GCMHelper gcmRegistrationHelper = new GCMHelper(getApplicationContext());
String gcmRegID = "";
gcmRegID = gcmRegistrationHelper.GCMRegister("123456");
// Update using Web Service
try {
UpdateGCMWSTask updateGCMWSTask = new UpdateGCMWSTask();
updateGCMWSTask.execute(UserID, gcmRegID);
// ************ HERE IS THE ERROR ***********************
}catch (Exception e)
{
e.printStackTrace();
}
} catch (Exception bug) {
bug.printStackTrace();
}
}
});
thread.start();
}
Add Looper.prepare() and Looper.loop() in you code, like this:
private void GetGCM(final String UserID) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
Looper.prepare();
GCMHelper gcmRegistrationHelper = new GCMHelper(getApplicationContext());
String gcmRegID = "";
gcmRegID = gcmRegistrationHelper.GCMRegister("123456");
// Update using Web Service
try {
UpdateGCMWSTask updateGCMWSTask = new UpdateGCMWSTask();
updateGCMWSTask.execute(UserID, gcmRegID);
// ************ HERE IS THE ERROR ***********************
}catch (Exception e)
{
e.printStackTrace();
}
Looper.loop();
} catch (Exception bug) {
bug.printStackTrace();
}
}
});
thread.start();
}
You can't create asynctask inside a thread. There are few ways to handle it:
Create a new handler.
Call function runOnUIThread of activity.
Using broadcast.
if the Callable() ScheduledThreadPoolExecutor is supposed to run in a background thread like Runnable() then why is it blocking my UI thread?
i thought is was supposed to run in a background thread like Runnable does.
ScheduledThreadPoolExecutor stpe;
inside of onCreate
ScheduledFuture<Integer> sf = stpe.schedule(new OtherObject2(), 5, TimeUnit.SECONDS);
try {
int returnedInteger = sf.get();
textViewThree.setText("the returned integer is: " + returnedInteger);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
nested inner class
public class OtherObject2 implements Callable<Integer> {
#Override
public Integer call() throws Exception {
Integer integerReturn = 23;
return integerReturn;
}
}
The following line int returnedInteger = sf.get(); blocks to wait for the result.
instead of return integerReturn in OtherObject2, run a special UI task:
final Integer integerReturn = 23;
runOnUiThread(new Runnable() {
public void run() {
textViewThree.setText("the returned integer is: " + integerReturn);
}
});
No need for OtherObject2 to implement Callable, Runnable is enough. No use of submitting OtherObject2 by schedule(), execute() is ok.
How to pass parameter to an already running thread in java -- not in the constructor, & probably without using wait() (possible ??)
Something similar to a comment in How can I pass a parameter to a Java Thread?
Do you mean passing a parameter to an already running thread ? Because all the current answers are about passing parameters to new threads... – Valentin Rocher May 18 '09 at 10:43
[edited]
yes, I was looking for something like the producer/consumer pattern.
I wanted something like a thread in which has the processing & is ready
for keyboard input. The other thread is just to monitor network and pass
on the received text to the processing thread.
Maybe what you really need is blocking queue.When you create the thread, you pass the blocking queue in and the thread should keep checking if there is any element in the queue. Outside the thread, you can put elements to the queue while the thread is "running". Blocking queue can prevent the thread from quit if their is nothing to do.
public class Test {
public static void main(String... args) {
final BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
Thread running = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
String data = queue.take();
//handle the data
} catch (InterruptedException e) {
System.err.println("Error occurred:" + e);
}
}
}
});
running.start();
// Send data to the running thread
for (int i = 0; i < 10; i++) {
queue.offer("data " + i);
}
}
}
The "other thread" will have its own life, so you can't really communicate with it / pass parameters to it, unless it actively reads what you gives to it.
A thread which you allows you to communicate with it typically reads data from some buffered queue.
Have a look at ArrayBlockingQueue for instance, and read up on the Consumer-Producer pattern.
public class T1 implements Runnable {
//parameter of thread T1
public static AtomicBoolean flag = new AtomicBoolean();
#Override
public void run() {
}
}
public class T2 implements Runnable {
#Override
public void run() {
//parameter to an already running thread
T1.flag.set(true);
}
}
What about such way:
class TestRun implements Runnable
{
private int testInt = -1;
public void setInt(int i)
{
this.testInt = i;
}
#Override
public void run()
{
while (!isFinishing())
{
System.out.println("Working thread, int : " + testInt);
try
{
Thread.sleep(2500);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
.....
TestRun first = new TestRun();
TestRun second = new TestRun();
(new Thread(first)).start();
(new Thread(second)).start();
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
}
first.setInt(101);
second.setInt(102);
I have a question relating to the timer function. I have managed to find the cause of my problem, but I'm not sure on how to address it. I will give you an overview of my function. It will first execute the cost() function, with a background thread working. However, what I realize was that my cost() function failed to load right at the beginning. Secondly, it's program to run every 60 secs which it failed as well. I check my code for my cost() function and it works fine if I call it down without the timer function. Could it be my Opencsv() function? The question is it due to constraint of the timer function or is there ways to address this issue?
public static void main(String[] args) {
launch(EVschedulerApp.class, args);
Timer timer = new Timer();
// timer.scheduleAtFixedRate(new Cost(), 10*1000, 10*1000);
timer.scheduleAtFixedRate(new Cost() {
#Override
public void run() {
new Thread(new Runnable() {
public void run() {
File file = new File("D:/test.csv");
if(file != null){
try {
Opencsv csv = new Opencsv();
csv.Csvreader();
} catch (IOException ex) {
Logger.getLogger(EVschedulerApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
else {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
}
}).start();
}
Opencsv class file:
public class Opencsv {
public void Csvreader() throws IOException {
try {
// TODO code application logic here
CSVReader reader = new CSVReader(new FileReader("D:/Test.csv"));
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
System.out.println(nextLine[0] + " " + nextLine[1]+ " " + nextLine[2]+ " " + nextLine[3]);
}
} catch (FileNotFoundException ex) {
Logger.getLogger(Opencsv.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Cost Class:
public class Cost extends TimerTask{
public void run() {
Calendar rightNow = Calendar.getInstance();
Integer hour = rightNow.get(Calendar.HOUR_OF_DAY);
if (hour==23 ) {
try {
URL tariff = new URL("http://www.******.downloadRealtime=true");
ReadableByteChannel tar = Channels.newChannel(Test.openStream());
FileOutputStream fos = new FileOutputStream("Test.csv");
fos.getChannel().transferFrom(tar, 0, 1<<24);
} catch (IOException ex) {
Logger.getLogger(Cost.class.getName()).log(Level.SEVERE, null, ex);
}
}
else {
}
}
I really think that your "bug" is not here, but somewhere else. Also you should be really looking at
ScheduledThreadPoolExecutor
instead of the Timer, it would be something like this :
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
executor.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
//Do your stuff in here
}
}), 60, TimeUnit.SECONDS );
Also may I recommend not to swallow the InterruptedExceptions - there are a lot of posts here on SO on this subject.
Cheers,
Eugene.
I think your bug is that you never call Cost's run() method, you are not just overriding it, you are hiding it. Try something like this:
timer.scheduleAtFixedRate(new Cost() {
#Override
public void run() {
super.run(); //Added this call to Cost's original method.
new Thread(new Runnable() {
public void run() {
//your code still here
}
}).start();
}
Although, as others point out, you should look into the Executor Service.
It seems that your bug is in class Cost that you have not posted here.
But anyway you have yet another problem here. Why do you create yet another thread inside run() of timer task. It may have sense only if your business logic takes significant time. In your case if your csv file is very large.
Start from simple implementation. Create task that synchronously pareses CSV. Schedule it and see how is it working. If and only if you see that task takes a lot of time thing about using yet another thread. In this case take a look on Executors.