I want use Huawei Push Kit in my Appcelerator Titanium app with Hyperloop.
var tokenString = '';
var Activity = require('android.app.Activity');
var ActivityToken = require('com.huawei.hms.aaid.HmsInstanceId');
try{
const activity = new Activity(Ti.Android.currentActivity);
tokenString = ActivityToken.getInstance(activity).getToken(appID, "HCM");
console.log('tokenString', tokenString);
}
catch (e){
console.log(e);
}
But I receive error: "operation in MAIN thread prohibited"
How do I run the code in a separate thread?
You could try the Automatic Initialization, by calling the setAutoInitEnabled(boolean enable) method in HmsMessaging.
ActivityToken.getInstance(activity).setAutoInitEnabled(true);
The applied token is returned through the onNewToken() method after completing the configuration.
Wrap around the code inside background thread, since the error says clearly that this can not be run on main thread. Time consuming calls are usually not allowed in main thread, onCreate etc.
Thread {
…
}.run()
Related
I have to launch the app on receiving notification. The following piece of code works fine when the app is killed and notification is received (i.e the code inside if condition). But when the app is running in foreground or background, multiple instances of the activity gets created(i.e snippet in else condition). It's not the MainActivity that has to be launched on receiving the notification, instead it's some other activity containing the broadcast Receiver.
I have added the following lines in the onMessage of GCMintentService class.
if (currentPackage.equalsIgnoreCase(context.getPackageName()
.toString())) {
broadcastMessage(context, message);
} else {
Intent mIntent = new Intent(context, MainActivity.class);
mIntent.setAction(Intent.ACTION_MAIN);
mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mIntent);
}
In the activity, under onReceive method of BroadcastReceiver, i am starting the activity again.
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
startActivity(getIntent().setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT));
}
};
I also had this requirement in one of my application. We can achieve it if we call
Intent mIntent = new Intent(context, MainActivity.class);
mIntent.setAction(Intent.ACTION_MAIN);
mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mIntent);
broadcastMessage(context, message);
In the main activity use the following in the broadcast receiver that would receive the broadcasted message above.
WakeLock wakeLock = null;
KeyguardManager kgMgr = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
boolean locked = kgMgr.inKeyguardRestrictedInputMode();
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
if (!pm.isScreenOn()) {
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP, "MyWakeLock");
wakeLock.acquire();
}
if (locked) {
Window mWindow = getWindow();
mWindow.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
mWindow.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
Personally I feel that this is not the best of the answers and also best of the ideas to open the app directly when received a notification as there will be many functions like onCreate onResume, will be triggered automatically, spoil the users work if they are in a really important work by opening another app directly, also we need to put a lot of flags or use any other method to manage the flow of the application, when user open the app, app comes from background, app opened due notification and all such cases. Avoid it as it spoils the whole user experience.
I'm using MVC 4 and I have the following code :
public void DoWork(string connectionId)
{
connectionId = this.connectionId;
var a = MakeADelayAsync();
}
public async Task MakeADelayAsync()
{
await Task.Delay(5000);
var generalHubContext = GlobalHost.ConnectionManager.GetHubContext<GeneralHub>();
generalHubContext.Clients.Client(connectionId).showNotification("Completed");
}
"DoWork" method is my mvc action. what I intent to do is when the action button is pressed the "DoWork" calls an async method and returns to the client immediately. when the async method has completed his job it will notify client using signalR.
The problem is in the "MakeADelayAsync" method, those two lines after await won't be called ever. It seems that the flow never continues after await.
First question is Where is the problem in "MakeADelayAsync" ?
Second question is why do I have to write a useless code of var a = MakeADelayAsync(); to avoid compiler warning while I'm completely aware of what I am doing? I never use "a" anyway.
"DoWork" method is my mvc action. what I intent to do is when the action button is pressed the "DoWork" calls an async method and returns to the client immediately. when the async method has completed his job it will notify client using signalR.
Doing this is extremely dangerous. I strongly recommend that you use a persistent queue, as I said in my previous answer: Azure queue, MSMQ, WebSphere MQ, etc.
However, if you insist on doing it the dangerous way, then you can use the code that I have on my blog to execute background work on ASP.NET outside of a request context:
public void DoWork(string connectionId)
{
connectionId = this.connectionId;
// This is extremely dangerous code! If ASP.NET unloads
// your app, then MakeADelayAsync may not run to completion.
BackgroundTaskManager.Run(() => MakeADelayAsync());
}
First question is Where is the problem in "MakeADelayAsync" ?
You're executing code that is attempting to resume on the request context after the request is completed and the request context is disposed. It's the same problem you had before.
Second question is why do I have to write a useless code of var a = MakeADelayAsync(); to avoid compiler warning while I'm completely aware of what I am doing?
The compiler warning is telling you that the code is almost certainly a mistake... and the compiler is right.
can you try to mark your DoWork method as async?
public async void DoWork(string connectionId)
{
connectionId = this.connectionId;
var a = MakeADelayAsync();
}
I have a web service in WCF that consume some external web services, so what I want to do is make this service asynchronous in order to release the thread, wait for the completion of all the external services, and then return the result to the client.
With Framework 4.0
public class MyService : IMyService
{
public IAsyncResult BeginDoWork(int count, AsyncCallback callback, object serviceState)
{
var proxyOne = new Gateway.BackendOperation.BackendOperationOneSoapClient();
var proxyTwo = new Gateway.BackendOperationTwo.OperationTwoSoapClient();
var taskOne = Task<int>.Factory.FromAsync(proxyOne.BeginGetNumber, proxyOne.EndGetNumber, 10, serviceState);
var taskTwo = Task<int>.Factory.FromAsync(proxyTwo.BeginGetNumber, proxyTwo.EndGetNumber, 10, serviceState);
var tasks = new Queue<Task<int>>();
tasks.Enqueue(taskOne);
tasks.Enqueue(taskTwo);
return Task.Factory.ContinueWhenAll(tasks.ToArray(), innerTasks =>
{
var tcs = new TaskCompletionSource<int>(serviceState);
int sum = 0;
foreach (var innerTask in innerTasks)
{
if (innerTask.IsFaulted)
{
tcs.SetException(innerTask.Exception);
callback(tcs.Task);
return;
}
if (innerTask.IsCompleted)
{
sum = innerTask.Result;
}
}
tcs.SetResult(sum);
callback(tcs.Task);
});
}
public int EndDoWork(IAsyncResult result)
{
try
{
return ((Task<int>)result).Result;
}
catch (AggregateException ex)
{
throw ex.InnerException;
}
}
}
My questions here are:
This code is using three threads: one that is instanced in the
BeginDoWork, another one that is instanced when the code enter
inside the anonymous method ContinueWhenAll, and the last one when
the callback is executed, in this case EndDoWork. Is that correct or
I’m doing something wrong on the calls? Should I use any
synchronization context? Note: The synchronization context is null
on the main thread.
What happen if I “share” information between
threads, for instance, the callback function? Will that cause a
performance issue or the anonymous method is like a closure where I
can share data?
With Framework 4.5 and Async and Await
Now with Framework 4.5, the code seems too much simple than before:
public async Task<int> DoWorkAsync(int count)
{
var proxyOne = new Backend.ServiceOne.ServiceOneClient();
var proxyTwo = new Backend.ServiceTwo.ServiceTwoClient();
var doWorkOne = proxyOne.DoWorkAsync(count);
var doWorkTwo = proxyTwo.DoWorkAsync(count);
var result = await Task.WhenAll(doWorkOne, doWorkTwo);
return doWorkOne.Result + doWorkTwo.Result;
}
But in this case when I debug the application, I always see that the code is executed on the same thread. So my questions here are:
3.. When I’m waiting for the “awaitable” code, is that thread released and goes back to the thread pool to execute more requests?
3.1. If So, I suppose that when I get a result from the await Task, the execution completes on the same thread that the call before. Is that possible? What happen if that thread is processing another request?
3.2 If Not, how can I release the thread to send it back to the thread pool with Asycn and Await pattern?
Thank you!
1. This code is using three threads: one that is instanced in the BeginDoWork, another one that is instanced when the code enter inside the anonymous method ContinueWhenAll, and the last one when the callback is executed, in this case EndDoWork. Is that correct or I’m doing something wrong on the calls? Should I use any synchronization context?
It's better to think in terms of "tasks" rather than "threads". You do have three tasks here, each of which will run on the thread pool, one at a time.
2. What happen if I “share” information between threads, for instance, the callback function? Will that cause a performance issue or the anonymous method is like a closure where I can share data?
You don't have to worry about synchronization because each of these tasks can't run concurrently. BeginDoWork registers the continuation just before returning, so it's already practically done when the continuation can run. EndDoWork will probably not be called until the continuation is complete; but even if it is, it will block until the continuation is complete.
(Technically, the continuation can start running before BeginDoWork completes, but BeginDoWork just returns at that point, so it doesn't matter).
3. When I’m waiting for the “awaitable” code, is that thread released and goes back to the thread pool to execute more requests?
Yes.
3.1. If So, I suppose that when I get a result from the await Task, the execution completes on the same thread that the call before. Is that possible? What happen if that thread is processing another request?
No. Your host (in this case, ASP.NET) may continue the async methods on any thread it happens to have available.
This is perfectly safe because only one thread is executing at a time.
P.S. I recommend
var result = await Task.WhenAll(doWorkOne, doWorkTwo);
return result[0] + result[1];
instead of
var result = await Task.WhenAll(doWorkOne, doWorkTwo);
return doWorkOne.Result + doWorkTwo.Result;
because Task.Result should be avoided in async programming.
If I try to access XAML controls inside a task (and task::then) my Metro XAML app always stops with an exception. The same code works without any problems outside the task. I didn't find any answer - what did I miss?
VS11 Debugger reports: Concurrency::unobserved_task_exception
Exception: The application called an interface that was marshalled for a different thread.
Many thanks for your help!
void MyClass::MyMemberFunction()
{
xamlStoryboard->Stop(); // ok
xamlImage->Source = ref new BitmapImage(); // ok
task<void> atask([this] ()
{
xamlStoryboard->Stop(); // exception!
xamlImage->Source = ref new BitmapImage(); //exception!
});
atask.then([this] ()
{
xamlStoryboard->Stop(); // exception!
xamlImage->Source = ref new BitmapImage(); //exception!
});
}
The atask.then() continuation code runs without exception if we add task_continuation_context::use_current()
as second parameter:
atask.then([this] ()
{
xamlStoryboard->Stop(); // now ok!
xamlImage->Source = ref new BitmapImage(); // now ok!
}, task_continuation_context::use_current());
You are calling your UI elements from a thread other than the UI/Dispatcher thread. You need to call your UI elements' methods using control.Dispatcher.InvokeAsync() or otherwise make sure you are not calling them from a background thread.
I have a question regarding the sequencing of events in the scenario where you are calling a wcf service from silverlight 3 and updating the ui on a seperate thread. Basically, I would like to know whether what I am doing is correct... Sample is as follows. This is my first post on here, so bear with me, because i am not sure how to post actual code. Sample is as follows :
//<summary>
public static void Load(string userId)
{
//Build the request.
GetUserNameRequest request =
new GetUserNameRequest { UserId = userId };
//Open the connection.
instance.serviceClient = ServiceController.UserService;
//Make the request.
instance.serviceClient.GetUserNameCompleted
+= UserService_GetUserNameCompleted;
instance.serviceClient.GetGetUserNameAsync(request);
return instance.VM;
}
/// <summary>
private static void UserService_GetUserNameCompleted(object sender, GetUserNameCompletedEventArgs e)
{
try
{
Controller.UIDispatcher.BeginInvoke(() =>
{
//Load the response.
if (e.Result != null && e.Result.Success)
{
LoadResponse(e.Result);
}
//Completed loading data.
});
}
finally
{
instance.serviceClient.GetUserNameCompleted
-= UserService_GetUserNameCompleted;
ServiceHelper.CloseService(instance.serviceClient);
}
}
So my question basically is, inside of my UI thread when I am loading the response if that throws an exception, will the "finally" block catch that ? If not, should i put another try/catch inside of the lambda where I am loading the response ?
Also, since I am executing the load on the ui thread, is it possible that the finally will execute before the UI thread is done updating ? And could as a result call the Servicehelper.CloseService() before the load has been done ?
I ask because I am having intermittent problems using this approach.
The finally block should get executed before the processing of the response inside the BeginInvoke. BeginInvoke means that the code will get executed in the next UI cycle.
Typically the best approach to this type of thing is to pull all the data you need out of the response and store it in a variable and then clean up your service code. Then make a call to BeginInvoke and update the UI using the data in the variable.