Back button not working in Native Activity - android-ndk

I have a native activity it works fine but when I hit the back button it stalls for a sec then I see...
I/InputDispatcher( 278): Application is not responding: AppWindowToken{411eb580 token=Token{40edc588 ActivityRecord{41180268 u0 com.gleason.native/android.app.NativeActivity}}}. It has been 5003.6ms since event, 5000.7ms since wait started. Reason: Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.
...
E/ActivityManager( 278): ANR in com.gleason.native (com.gleason.native/android.app.NativeActivity)
E/ActivityManager( 278): Reason: keyDispatchingTimedOut
I have an example of my code here

Adding this fixed it....
while (1) {
int ident;
int events;
struct android_poll_source* source;
while ((ident=ALooper_pollAll(-1, NULL, &events,
(void**)&source)) >= 0) {
if (source != NULL) {
source->process(state, source);
}
if (state->destroyRequested != 0) {
term_display();
return;
}
}
}

Related

How to sleep/wait within an app without making the UI unresponsive

I'm developing an app for Windows in Visual C++ which would get inputs from a web API. Some of the API calls require me to request response in some specified time delay and during this time I would like to display a spinner.
I'm all good with the displaying spinner, disabling the buttons etc for the time I need to wait before proceeding to the request, but don't know how to pause the process within the app. Obviously, if I use the _sleep function, the app becomes unresposive.
Here's more or less what I need to achieve (pseudo-code)
void doSomething()
{
ui->button1->setEnable(false);
SendAPIReuqest1();
while (APIRequest1_success)
{
requestAPIRequest1_response();
//wait 10s if false and retry, this can take up to 5mins
}
SendAPIRequest2();
//wait 30s - here I know I can start the job on my end exactly after 30s
doSometing2();
ui->button1->setEnable(true);
}
What would be the correct approach to achieve what I need?
You'll most likely just want to poll for a response from the web API, alternatively you can start a secondary thread to check for a response from the web API;
After seeing some minimal code, something similar to this may work.
//takes an initial start time, calculates elapsed time, compares elapsed time to count
bool ready(std::chrono::time_point<std::chrono::system_clock>&start, const double& count) {
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> diff = end-start;
if (diff.count() >= count) {
start = end;
return true;
}
return false;
}
void doSomething()
{
static std::chrono::time_point<std::chrono::system_clock> start;
static int state = 0;
switch(state) {
case (0):
ui->button1->setEnable(false);
SendAPIRequest1();
if (APIRequest1_success) {
start = std::chrono::system_clock::now();
++state;
}
break;
case (1):
if (ready(start, 10.0) && requestAPIRequest1_response()) ++state;
break;
case(2):
SendAPIRequest2();
start = std::chrono::system_clock::now();
++state;
break;
case(3):
if (ready(start, 30.0)) {
doSomething2();
ui->button1->setEnable(true);
state = 0;
}
break;
}
}
This way you can call the function and it will either attempt one of the requests or return to do other tasks.
or with threads it could be as simple as
void worker_func(std::promise<bool>&& result) {
using namespace std::chrono_literals;
SendAPIRequest1();
while (!requestAPIRequest1_response()) {
std::this_thread::sleep_for(10s);
}
SendAPIRequest2();
std::this_thread::sleep_for(30s);
doSomething2();
result.set_value(true);
}
void doSomething() {
static std::future<bool> finished;
static bool flag = true;
if (flag) {
std::promise<bool> _finished;
finished = _finished.get_future();
ui.button1.setEnable(false);
std::thread worker(worker_func, std::move(_finished));
flag = false;
} else if (finished.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
//finished.get();
worker.join();
ui.button1.setEnable(true);
flag = true;
}
}
This way your main thread can keep running the ui, while the worker thread waits for the web API response, as long as your requests aren't handling any QT ui components I believe this should work.
Edit:
Since I have never used QT and it was never mentioned originally that QT was being used the above answers may or may not be usefull, however it looks like QT has some functions to handle things like this. maybe you can just start and stop a Qtimer
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &foo::update);
timer->start(1000);
would run the function foo::update() every second, the time interval can be changed accordingly. Here is a reference to QTimer and a reference to another class which may be of interest QTimerEvent not to mention, QT has an entire event handling system The Event System

My code doesn't receive a message from xserver

I want to receive a message from xserver when I close my window.
(when I hit the 'X' button')
For example, I have a list of windows that are currently opened. (can be referred by dayRecord.)
I want to print that "window closed!" when I click the x button on a terminal.
But though I clicked it, I couldn't get any message from xserver.
Also, that XNextEvent is blocking.
I've test this exact same logic with a window generated in my code using XCreateSimpleWindow,
and it worked perfectly.
I can even close an existing window I created manualy by XDestroyWindow.
So, I think there is no difference between a window that is created by the code
and created before the code starts once if I have a window id.
But somehow, I cannot get any message from a former one.
This is my code.
It is trying to get a list of windows that are opened.
And within them, when I close a terminal it should print "window closed!"
void windowManager() {
// getting a text viewer to be traced
char **textViewers = getTextViewers();
// retreiving new record of a day
DayRecord *dayRecord = getNewDayRecord();
// save an x11 display, and currently opened windows into the day record
Display *display = recordInit(dayRecord);
Window whatToClose;
for (int i = 0; i < dayRecord->recordCnt; ++i) {
printf("currently opened: %s %lu\n", dayRecord->record[i].name, dayRecord->record[i].window);
// for example: i want to know when a terminal is closed. (before the program starts, it should be opened, or it crashes.)
if (strcmp(dayRecord->record[i].name, "gnome-terminal-server") == 0)
whatToClose = dayRecord->record[i].window;
addInfoSpace(display, dayRecord->record + i, textViewers);
}
printf("let's close %lu: %s\n", whatToClose, getWindowName(display, whatToClose));
// window close detecting logic down here...
Atom wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, whatToClose, &wmDelete, 1);
XEvent xEvent;
printf("I am listening!\n");
while (True) {
XNextEvent(display, &xEvent);
if (xEvent.type == ClientMessage && xEvent.xclient.data.l[0] == wmDelete) {
printf("window closed!\n");
break;
}
}
char *json = (char *)malloc(sizeof(char) * 100000);
dayRecordToJSON(dayRecord, json);
printf("%s", json);
// freeing memories
free2dArray((void **)textViewers, MAX_FILE_COUNT);
freeDayRecord(dayRecord);
XCloseDisplay(display);
}
Thank you.
I've tried many things and this worked.
If you're trying to do the same thing, please check the code.
But, I am not sure if this is a right way to do.
Maybe there can be a safer and right way to do this but this works anyway.
// ...
Atom wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, whatToClose, &wmDelete, 1);
XSelectInput(display, whatToClose, SubstructureNotifyMask);
XEvent xEvent;
printf("I am listening!\n");
while (1) {
XNextEvent(display, &xEvent);
if (xEvent.type == DestroyNotify) {
printf("window closed!\n");
break;
}
}
// ...

Multithreaded program hangs on control method call

I've got a UI with 2 buttons and a textbox.
When the user presses the "Receive" button, a thread is started for an infinite work loop (receiving and printing messages from multicast). When the user presses the "Stop" button, the thread is given it's "kill flag" and then the program waits for the Join() to finish.
That infinite work loop calls back to the UI textbox with a SetTextBoxText(System::String) method. This is causing a race condition. Sometimes, the thread finishes the Join() just fine. Others, the program hangs forever on the Join().
I believe this is because when the UI thread calls Join() on its work thread, the work thread may be in the middle of its loop and is trying to invoke a locked thread. The UI thread is waiting for the Join() and is unable to do anything (like SetTextBoxText).
So, race-condition or deadlock, I need a way to check if the control is usable. If it is, then call the method to print like normal. If it is not usable, then don't try to call the SetTextBoxText method and continue like normal.
Code time, I'm actually using a UserControl, not a separate textbox, button1, and button2. I call the UserControl "MyUserControl". It contains the following code:
System::Void MyUserControl::buttonReceive_Click(System::Object^ sender, System::EventArgs^ e)
{
//each MyUserControl has their own myThread
this->myThread = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this, &MyUserControl::WorkLoop));
this->workLoopFlag = true;
this->myThread->Start();
}
void MyUserControl::WorkLoop()
{
while (this->workLoopFlag == true)
{
System::Threading::Thread::BeginCriticalRegion();
//this->myThread->BeginCriticalRegion();
Process();
//this->myThread->EndCriticalRegion();
System::Threading::Thread::EndCriticalRegion();
}
}
void EntityStatePduProcessor::Process()
{
//These 2 lines are for getting the correct MyUserControl to edit. Stored in GlobalVars::myList
ThreadPredicate^ threadPred = gcnew ThreadPredicate(System::Threading::Thread::CurrentThread->ManagedThreadId);
UserControlDataCollection^ userControlDataColl = GlobalVars::myList->Find(gcnew System::Predicate<UserControlDataCollection^>(threadPred, &ThreadPredicate::IsMatch));
System::Threading::Thread::BeginCriticalRegion();
if (userControlDataColl != nullptr) //should only happen after killing a thread
{
MyUserControl^ controlToEdit = (MyUserControl^)System::Windows::Forms::Control::FromHandle(userControlDataColl->control);
if (controlToEdit != nullptr)
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
controlToEdit->SetTextBoxConsoleText("a system::string to place into the textbox");
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
else
{
System::Windows::Forms::MessageBox::Show("controlToEdit == nullptr");
}
}
System::Threading::Thread::EndCriticalRegion();
}
delegate void MyStringDelegate(System::String ^ text);
void MyUserControl::SetTextBoxConsoleText(System::String^ input)
{
if (this->InvokeRequired) // (this->consoleTextBox->InvokeRequired)
{
MyStringDelegate^ myStrDel = gcnew MyStringDelegate(this, &MyUserControl::SetTextBoxConsoleText);
this->Invoke(myStrDel, gcnew array<Object^> { input });
}
else
{
this->textBoxConsole->Text = input;
this->textBoxConsole->Refresh();
}
}
System::Void MyUserControl::buttonStop_Click(System::Object^ sender, System::EventArgs^ e)
{
this->workLoopFlag = false; // kill the endless while loop
this->myThread->Join();
}
I tried to post the code in chronological order and only include the essentials while explaining the gaps in //comments.
The code that causes the hang is in the 3rd method shown Process() outlined with //~~~.
How do I correctly ensure that the controlToEdit is still able to access and not just waiting on a Join()?

WP7 - Having trouble gracefully exiting bg thread on app deactivate or closing

My somewhat data-intensive wp7 app persists data as follows: I maintain a change journal reflecting all user activity, and every couple of seconds, a thread timer spins up a threadpool thread that flushes the change journal to a database inside a transaction. It looks something like this:
When the user exits, I stop the timer, flush the journal on the UI thread (takes no more than a second or two), and dismount the DB.
However, if the worker thread is active when the user exits, I can't figure out how to react gracefully. The system seems to kill the worker thread, so it never finishes its work and never gives up its lock on the database connection, and the ui thread then attempts to acquire the lock, and is immediately killed by the system. I tried setting a flag on the UI thread requesting the worker to abort, but I think the worker was interrupted before it read the flag. Everything works fine except for this 1 in 100 scenario where some user changes end up not being saved to the db, and I can't seem to get around this.
Very simplified code below:
private Timer _SweepTimer = new Timer(SweepCallback, null, 5000, 5000);
private volatile bool _BailOut = false;
private void SweepCallback(object state) {
lock (db) {
db.startTransaction();
foreach(var entry in changeJournal){
//CRUD entry as appropriate
if(_BailOut){
db.rollbackTransaction();
return;
}
}
db.endTransaction();
changeJournal.Clear();
}
}
private void RespondToSystemExit(){
_BailOut = true; //Set flag for worker to exit
lock(db){ //In theory, should acquire the lock after the bg thread bails out
SweepCallback(null);//Flush to db on the UI thread
db.dismount();//App is now ready to close
}
}
Well, just to close this question, I ended up using a manualresetevent instead of the locking, which is to the best of my understanding a misuse of the manualresetevent, risky and hacky, but its better than nothing.
I still don't know why my original code wasn't working.
EDIT: For posterity, I'm reposting the code to reproduce this from the MS forums:
//This is a functioning console app showing the code working as it should. Press "w" and then "i" to start and then interrupt the worker
using System;
using System.Threading;
namespace deadlocktest {
class Program {
static void Main(string[] args) {
var tester = new ThreadTest();
string input = "";
while (!input.Equals("x")) {
input = Console.ReadLine();
switch (input) {
case "w":
tester.StartWorker();
break;
case "i":
tester.Interrupt();
break;
default:
return;
}
}
}
}
class ThreadTest{
private Object lockObj = new Object();
private volatile bool WorkerCancel = false;
public void StartWorker(){
ThreadPool.QueueUserWorkItem((obj) => {
if (Monitor.TryEnter(lockObj)) {
try {
Log("Worker acquired the lock");
for (int x = 0; x < 10; x++) {
Thread.Sleep(1200);
Log("Worker: tick" + x.ToString());
if (WorkerCancel) {
Log("Worker received exit signal, exiting");
WorkerCancel = false;
break;
}
}
} finally {
Monitor.Exit(lockObj);
Log("Worker released the lock");
}
} else {
Log("Worker failed to acquire lock");
}
});
}
public void Interrupt() {
Log("UI thread - Setting interrupt flag");
WorkerCancel = true;
if (Monitor.TryEnter(lockObj, 5000)) {
try {
Log("UI thread - successfully acquired lock from worker");
} finally {
Monitor.Exit(lockObj);
Log("UI thread - Released the lock");
}
} else {
Log("UI thread - failed to acquire the lock from the worker");
}
}
private void Log(string Data) {
Console.WriteLine(string.Format("{0} - {1}", DateTime.Now.ToString("mm:ss:ffff"), Data));
}
}
}
Here is nearly identical code that fails for WP7, just make a page with two buttons and hook them
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows;
using Microsoft.Phone.Controls;
namespace WorkerThreadDemo {
public partial class MainPage : PhoneApplicationPage {
public MainPage() {
InitializeComponent();
}
private Object lockObj = new Object();
private volatile bool WorkerCancel = false;
private void buttonStartWorker_Click(object sender, RoutedEventArgs e) {
ThreadPool.QueueUserWorkItem((obj) => {
if (Monitor.TryEnter(lockObj)) {
try {
Log("Worker acquired the lock");
for (int x = 0; x < 10; x++) {
Thread.Sleep(1200);
Log("Worker: tick" + x.ToString());
if (WorkerCancel) {
Log("Worker received exit signal, exiting");
WorkerCancel = false;
break;
}
}
} finally {
Monitor.Exit(lockObj);
Log("Worker released the lock");
}
} else {
Log("Worker failed to acquire lock");
}
});
}
private void Log(string Data) {
Debug.WriteLine(string.Format("{0} - {1}", DateTime.Now.ToString("mm:ss:ffff"), Data));
}
private void buttonInterrupt_Click(object sender, RoutedEventArgs e) {
Log("UI thread - Setting interrupt flag");
WorkerCancel = true;
//Thread.Sleep(3000); UNCOMMENT ME AND THIS WILL START TO WORK!
if (Monitor.TryEnter(lockObj, 5000)) {
try {
Log("UI thread - successfully acquired lock from worker");
} finally {
Monitor.Exit(lockObj);
Log("UI thread - Released the lock");
}
} else {
Log("UI thread - failed to acquire the lock from the worker");
}
}
}
}
Your approach should work when you operate from the Application_Deactivated or Application_Closing event. MSDN says:
There is a time limit for the Deactivated event to complete. The
device may terminate the application if it takes longer than 10
seconds to save the transient state.
So if you say it just takes just a few seconds this should be fine. Unless the docs don't tell the whole story. Or your worker thread takes longer to exit than you think.
As Heinrich Ulbricht already said you have <=10 sec to finish your stuff, but you should block MainThread to get them.
It means that even if you have BG thread with much work to do, but your UI thread just does nothing in OnClosingEvent/OnDeactivatingEvent - you will not get your 10 seconds.
Our application actually does eternal wait on UI thread in closing event to allow BG thread send some data thru sockets.

How to apllcation can catch the event set by driver in wince 6.0?

I have wince 6.0 applcaion in which inside thread applcation is waiting for event which driver will set. i have created event inside applcation and samevent in driver also. butwhen driver set the event then appcation is not able to catch it.(driver is setting event successfully)
Here is code
// application side
m_hEvent = CreateEvent(NULL,FALSE,FALSE,L"MY_EVENT");
if(m_hEvent)
{
if(!DeviceIoControl(m_hDriver,CREATE_MY_EVENT,
(LPDWORD)&m_hEvent,NULL,NULL,NULL,NULL,NULL))
{
AfxMessageBox(L"not created event successfully in driver");
}
while(TRUE)
{
//waiting for driver to setevent
int RetValue = WaitForSingleObject(m_hEvent,INFINITE);
if(0 == RetValue )
{
AfxMessageBox(L"wait end");
}
else
{
AfxMessageBox(L"time out");
}
}
}
...
//Driver side
BOOL SMP_IOControl(DWORD hOpenContext, DWORD dwCode,
LPDWORD pBufIn, DWORD dwLenIn, LPDWORD pBufOut,
DWORD dwLenOut, PDWORD pdwActualOut)
{
switch (dwCode)
{
case CREATE_MY_EVENT :
{
m_hEvent = (HANDLE)(*pBufIn);
if(NULL != m_hEvent)
{
// getting this message
MessageBox(NULL,L"event successfully created",L"success",MB_OK);
}
else
{
MessageBox(NULL,L"no event successfully created",L"success",MB_OK);
}
}
break;
case SET_EVENT:
{
//set event that which application waiting
if(SetEvent(m_hEvent))
{
// getting this message
MessageBox(NULL,L"event set successfully",L"success",MB_OK);
}
else
{
MessageBox(NULL,L"event set successfully",L"success",MB_OK);
}
}
break;
}
}
The inherent problem here is that you're having one process (your app) create a HANDLE and then passing that HANDLE to the another process (device.exe) and expecting it to be valid. It's not.
In this case the solution is simple. System events are unique across the OS by name, so simply call CreateEvent in both places using the same text name. When you call SetEvent in one process, the other process waiting on the HANDLE it created will get signalled.
That means remove your CREATE_MY_EVENT IOCTL (and that's a non-standard naming convention, BTW, it should start with "IOCTL_") handling in the driver and just call CreateEvent in the SMP_Init method and store that HANDLE.

Resources