I have been developing a project for my client. It is a type of social media application.
The database is firebase and it is written in java and some kotlin.
The debug apk was fine.
I have tested it and also used it but when I try to release the app on playstore, I have to generate a signed apk, but the signed apk is not like debug apk it has many bugs.
I don’t know what’s happening, please help me.
Thank you in advance.
I had similar problem. Only now I discovered that the standard intellIj and Android Studio mode are debug mode.
I reviewed the threads of my application on release mode, and replaced the threads of type 1 for threads of type 2:
Threads Type 1:
class TimeCheckURL extends TimerTask
{
#RequiresApi(api = Build.VERSION_CODES.M)
public void run()
{
new Thread(new Runnable() {
#Override
public void run() {
Data = null;
Data = new JsonTask().execute(urlBase);
threadEnd = true;
}
}).start();
}
}
Threads Type 2:
Thread threadReadHexBsvTx = new Thread(new Runnable() {
#Override
public void run() {
try {
Data = JsonTask(urlBase);
} catch (Exception e) {
e.printStackTrace();
}
}
});
private void renewThread()
{
threadReadHexBsvTx = new Thread(new Runnable() {
#Override
public void run() {
try {
Data = JsonTask(urlBase);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
To monitor if threads type 1 were still alive I used the following approach;
while (!threadEnd) {
//do something
}
It worked very well when I unknowingly developed under Build Variant Debug, however when I put it on playstore I discovered that there was a release variant, and that my application did not worked properly on release mode.
It happened because everytime the processes using threads type 1 were called for the second time, the thread did not updated "threadEnd" and it looped forever.
I discovered that I could monitor the state of thread type 2 using this aproach.
while (bsvTX.threadBroadCast.isAlive()) {
//do something
}
This solved the problem in my application. However, I could not use approach of thread type 2 on thread type 1.
It might sound very noob, but I also discovered that for threads type 2 to work the second time the processes called them, they had to be renewed, that is why I use the method renewThread().
Related
I have a simple thread like this.
public class CameraThread extends Thread {
private AtomicBoolean runCamera;
public CameraThread(AtomicBoolean runCamera) {
this.runCamera = runCamera;
}
#Override
public void run() {
while (Main.RUNTHREAD) {
while (runCamera.get()) {
Platform.runLater(() -> {
System.out.println("Hello");
threadSleep();
});
}
}
}
private void threadSleep() {
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And when I set runCamera to runCamera.set(true) utside from the thread, the whole GUI freezes and I cannot do anything.
This is a minimal example and I can't get it to work properly.
I have used RunLater command before, but this time, I'm sitting at a Dell precision M6400 machine from 2007. Could it happen that this machine cannot handle threads with Java?
Or how can I solve this issue?
To reproduce this issue, just type the following:
wget https://github.com/DanielMartensson/Darknet-Data-Creator/archive/main.zip
unzip Darknet-Data-Creator-main.zip
cd Darknet-Data-Creator-main
mvn javafx:run
Then click on Scan button, select a web camera (USB, laptop camera) and then press Save to folder button. Just select some arbitary folder. Then press Open camera button
The issue is that you are using Thread.Sleep() inside Platform.runLater(...), which means that you are sleeping the GUI, not your camera thread.
Try this instead, note how runLater is outside of the Platform.runLater code:
#Override
public void run() {
while (Main.RUNTHREAD) {
while (runCamera.get()) {
Platform.runLater(() -> {
System.out.println("Hello");
});
//Now thread sleep is outside of runLater:
threadSleep();
}
}
}
The only thing that should go inside the runlater is things that directly change the GUI. Any calculation, sleeping, processing, file reading etc should be kept separate.
I'm currently developing a Vaadin-based program in Java which extracts documents from Domino databases and writes them to a MongoDB collection. The program works perfectly but has one small flaw:
Currently i've found no way to stop the program other then send "KILL" to the process. My shutdown hook/signal handler is totally ignored. I've narrowed down the problem to a single line of code:
NotesThread.sinitThread();
When i remove this line, the hook works perfectly and my program is shutdown properly. When the line is inserted, then the hook is never called.
Here is some example code:
private boolean running = true;
...
#Override
public void run() {
try {
NotesGC.runWithAutoGC(() -> {
NotesThread.sinitThread() // --> "Kills" all signal handling
Session session = NotesFactory.createSession();
while (running) {
Thread.sleep(1000);
System.out.println("Running ...");
}
session.recycle();
return null;
});
} catch (Exception e) {
} finally {
NotesThread.stermThread();
}
}
public void kill() {
System.out.println("Killed!");
this.running = false;
}
...
Signal.handle(new Signal("TERM"), sig -> runner.kill()); // Signal handler from main-method
I've asks friends and colleagues and nobody ever had the same problem.
NotesGC.runWithAutoGC
As I see you are using Domino JNA, a side project.
It use the domino CAPI.
It's open source: https://github.com/klehmann/domino-jna
You can create issue ticket or ask question.
BTW, func "runWithAutoGC" call initThread() in his body.
This link for source code: https://github.com/klehmann/domino-jna/blob/master/domino-jna/src/main/java/com/mindoo/domino/jna/gc/NotesGC.java
For instance consider the below scenario.
App1: I have a multiple-threaded java app, which enters a lot of files in DB.
App2: when i access the DB using some other app, its slow in fetching results.
So when both apps work simultaneously, it takes great time for DB fetching results on the front-end app2.
Here, i want to pause all transactions(threads) on App1 for some 'x min' time. Considering a trigger has already been installed when app 2 is being used. So when App2 is idle, App1 will resume as if nothing happened. Please list some or one best approach to achieve this
Map<Thread, StackTraceElement[]> threads = Thread.getAllStackTraces();
for (Map.Entry<Thread, StackTraceElement[]> entry : threads.entrySet()) {
entry.getKey().sleep();
}
This didn't worked well.
Just to try:
private List<PausableThread> threads = new ArrayList<PausableThread>();
private void pauseAllThreads()
{
for(PausableThread thread : this.threads)
{
thread.pause();
}
}
And your Thread class will be something like this:
public class MyThread extends Thread implements PausableThread
{
private boolean isPaused = false;
#Override
public void pause()
{
this.isPaused = true;
}
#Override
public void run()
{
while(!Thread.currentThread().isInterrupted())
{
// Do your work...
// Check if paused
if(this.isPaused)
{
try
{
Thread.sleep(10 * 1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
And the PausableThread interface:
public interface PausableThread
{
void pause();
}
Posting a solution answer, for my scenario.
I created a global flag and used it as a switch.
SO now, before DB interaction i just added a condition [in various functions where threads were performing variety of jobs, this solved the instance issue i was worried about]
if(isFlagChecked){thread.sleep(someDefinedTime);}
wait here if flag is true
continue with business logic...[db transacts here]
So, my issue was solved with just this, although it wouldn't pause thread running in intermediate state, which is kind of a good thing - one less trouble.
Parallel, in my trigger function - i checked for the elapsed time and changed the flag to false after desired time has passed. Check code skeleton below.
#async
void pause() // triggered by parallel running app when required
{
isFlagChecked=true;
resumeTime=new Date(timeInMillis + (someDefinedTime)) // resume time to switch flag condition
while (true) {
if (new Date().compareTo(resumeTime) > 0)
isFlagChecked=false;
}
}
Tried and tested, all running well, the performance improved significantly [least for my scenario].
I want to sandbox an application where end users can submit Java code to a server where it is compiled and executed (kind of a web-based IDE as part of an educational game). Most aspects can easily be handled by using either the standard security manager or verification of used APIs against a whitelist using ASM or similar.
An open problem is how to deal with infinite loops. As threads have their own stack, StackOverFlowErrors seem to be thread-local. I have done a little spike and came up with this:
public class TryToSurviveAStackOverflow {
public static void main(String[] args) throws Exception {
final Runnable infiniteLoop = new Runnable() {
#Override public void run() {
run();
}
};
Runnable sandboxed = new Runnable() {
#Override public void run() {
try {
Thread.sleep(10000); // some time to connect VisualVM to monitor this
infiniteLoop.run();
}
catch (StackOverflowError x) {
System.err.println("Thread crashed with stack overflow");
} catch (InterruptedException e) {
System.err.println("Thread interruped");
}
}
};
Thread thread = new Thread(sandboxed,"infinite loop");
thread.start();
thread.join();
System.out.println(thread.getState());
System.out.println("I am still alive");
}
}
This seems to work, but how safe is this? In particular, what happens to the stack space used by the unsafe thread? I can see that the state of the thread is set to TERMINATED.
Any help / pointers are highly appreciated !
Cheers, Jens
I want to make a thread, which runs, computes something with the data i give it, and returns a few values, or an object. The thread is a part of a Swing GUI.
My question: How can I make a method that runs when I make the thread, and returns an object (or whatever I want it to return)?
My code:
private void nextTurn () {
// do something
if (turn == white) {
try {
Engine e = new Engine(); // Engine is implemented by runnable
e.start();
Move m = e.getBestMove (board);
// thread should work, next code should be excecuted immediately
}
catch (Exception e) {}
}
// end of Main class
}
This is the first time I am working with Threads, and I know you should avoid them if possible, but I need it this time for my GUI.
The info on the Oracle site on Threads did not help me out. I am able to make a program with multiple Threads that runs indefinately, but I can't make it work with functions.
Since this is with a Swing GUI, consider using a SwingWorker object which creates a background thread (all the code run in the doInBackground method), and then can return a final result and/or interim results. Information on how to use this is well documented in the tutorials here:
Concurrency in Swing
SwingWorkers have property change support and thus will allow listeners to observe its state (as a SwingWorker.StateValue) via a PropertyChangeListener. This is one way your program can determine that the thread has completed its processing, get the returned result and go from there.
On an unrelated note, this isn't in your production code is it?:
catch (Exception e) {}
If so, you will likely want to fix this as ignored exceptions can bite you in the tail big time.
e.g.,
if (turn == white) {
try {
final SwingWorker<Move, Void> mySwingWorker = new SwingWorker<Move, Void>() {
#Override
protected Move doInBackground() throws Exception {
Engine e = new Engine(); // Engine is implemented by runnable
e.start();
Move m = e.getBestMove(board);
return m;
}
};
mySwingWorker.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (StateValue.DONE == mySwingWorker.getState()) {
try {
Move m = mySwingWorker.get();
// TODO: insert code to run on the EDT after move determined
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
});
mySwingWorker.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
I suggest you use an ExecutorService. It allows you to create a thread pool, you can pass tasks to it and get the results later.
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html