Navigation problems with MVVMLight - xamarin.ios

I'm having a couple of issues when trying to navigate using MVVMLight.
On iOS, I have created my NavigationService in AppDelegate/FinishedLoading with the following code
var nav = new NavigationService();
nav.Configure(ViewModelLocator.MainPageKey, "MainPage");
nav.Configure(ViewModelLocator.MapPageKey, "MapPage");
// iOS uses the UINavigtionController to move between pages, so will we
nav.Initialize(Window.RootViewController as UINavigationController);
// finally register the service with SimpleIoc
SimpleIoc.Default.Register<INavigationService>(() => nav);
When I use NavigateTo to move between the two pages, I continually get the same error asking if I have called NavigationService.Initialize. Obviously I have. The first ViewController shows without a problem.
On Android, I'm having issues again with the second Activity, but with a different error.
I am passing a List< double> as the object parameter in NavigateTo and then in the Activity, use the following to retrieve the passed object
void GetDataFromViewModel()
{
var NavService = (NavigationService)SimpleIoc.Default.GetInstance<INavigationService>();
var data = NavService.GetAndRemoveParameter<object>(Intent) as List<double>;
if (data != null)
{
ViewModel.Latitude = data[0];
ViewModel.Longitude = data[1];
}
}
Problem is that straight after the base.OnCreate in my OnCreate method, the app crashes out with the error
UNHANDLED EXCEPTION:
[MonoDroid] System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Microsoft.Practices.ServiceLocation.ActivationException: Type not found in cache: System.Object.
My NavigateTo line looks like this
INavigationService navigationService;
...code
navigationService.NavigateTo(ViewModelLocator.MapPageKey, new List<double> { Latitude, Longitude });
This has got me stumped!

Related

Capturing every frame to recognize text ARcore - Do i need to use semaphores?

I am developing an app in which I want to recognize text in real-time.
At first I was using onTapListener so whenever the user was tapping on the screen the current frame was being captured and after that the text recognition was called.
Right now I want to do this completely real-time so the user will not tap on the screen to capture the current frame. But every current frame is going to be captured until the moment the text of one captured current frame will be recognized.
For this reason, I created a global boolean field name locked that is initialized in false and I use it as a "locker" as you will see in a bit.
private boolean locked = false;
And in a method onUpdateFrame(FrameTime frameTime) I use the above global variable locked. When the first feature points are tracked I "lock" the update. So only the current thread gonna capture the current frame. And if the recognized data is null the I put locked = true so the next frame gonna be captured.
This is my code
public void onUpdateFrame(FrameTime frameTime) {
Frame frame = arFragment.getArSceneView().getArFrame();
// If there is no frame, just return.
if (frame == null) {
return;
}
//Making sure ARCore is tracking some feature points, makes the augmentation little stable.
if(frame.getCamera().getTrackingState()==TrackingState.TRACKING && !locked) {
locked = true;
if (mProgressDialog == null) {
mProgressDialog = ProgressDialog.show(this, "Processing",
"OCR...", true);
} else {
mProgressDialog.show();
}
executor.execute(() -> {
Bitmap b = captureImage();
final String[] text = {getOCRResult(b)};
handler.post(() -> {
if(text[0] != null && !text[0].equals("")){
doSomething();
}
else{
locked = false;
}
}
This is not working though. And my app is crashing immediately when is detecting the surface.
I am getting the following error, and the Toast that the error talks about it refers to a Toast that I have inside the method captureImage()
E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
Process: opencv.org, PID: 27860
java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()
I cant understand what I am doing wrong.
I heard of semaphores and this is why I asked that on my question. Should i use semaphores , do i need something like that so my app will work. As i understand i need one thread anytime to do the capture of the current frame.
Could someone help me i am a bit lost?
thank you
The reason you are getting this error is that you can't show a toast, or any UI, on a non-UI thread.
The usual way to handle this is to create a 'Handler' on the UI thread and send a message to its message queue asking it to post the thread.
You can see examples in both Java and Kotlin in this answer: Can't create handler inside thread that has not called Looper.prepare()
More info on Handler here: https://developer.android.com/reference/android/os/Handler

Cocos2d-x Multithreading sceanrio crashes the game

my scenario is simple:i made a game using cocos2d-x and i want to download images (FB and Google play) for multi player users and show them once the download is done as texture for a button.
in ideal world, things work as expected.
things get tricky when those buttons got deleted before the download is done.
so the callback function is in weird state and then i get signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
and the app crashes
This is how i implmented it
I have a Layout class called PlayerIcon. the cpp looks like this
void PlayerIcon::setPlayer(string userName, string displayName, string avatarUrl){
try {
//some code here
downloadAvatar(_userName, _avatarUrl);
//some code here
}
catch(... ){
}
}
void PlayerIcon::downloadAvatar(std::string _avatarFilePath,std::string url) {
if(!isFileExist(_avatarFilePath)) {
try {
auto downloader = new Downloader();
downloader->onFileTaskSuccess=CC_CALLBACK_1(PlayerIcon::on_download_success,this);
downloader->onTaskError=[&](const network::DownloadTask& task,int errorCode,
int errorCodeInternal,
const std::string& errorStr){
log("error while saving image");
};
downloader->createDownloadFileTask(url,_avatarFilePath,_avatarFilePath);
}
catch (exception e)
{
log("error while saving image: test");
}
} else {
//set texture for button
}
}
void PlayerIcon::on_download_success(const network::DownloadTask& task){
_isDownloading = false;
Director::getInstance()->getScheduler()-> performFunctionInCocosThread(CC_CALLBACK_0(PlayerIcon::reload_avatar,this));
}
void PlayerIcon::reload_avatar(){
try {
// setting texture in UI thread
}
catch (...) {
log("error updating avatar");
}
}
As i said, things works fine until PlayerIcon is deleted before the download is done.
i dont know what happens when the call back of the download task point to a method of un object that s deleted (or flagged for deletion).
i looked in the downloader implementation and it doesn't provide any cancellation mechanism
and i'm not sure how to handle this
Also, is it normal to have 10% crash rate on google console for a cocos2dx game
any help is really appreciated
Do you delete de Downloader in de destructor of the PlayerIcon?
there is a destroy in the apple implementation witch is trigered by the destructor.
-(void)doDestroy
{
// cancel all download task
NSEnumerator * enumeratorKey = [self.taskDict keyEnumerator];
for (NSURLSessionDownloadTask *task in enumeratorKey)
{
....
DownloaderApple::~DownloaderApple()
{
DeclareDownloaderImplVar;
[impl doDestroy];
DLLOG("Destruct DownloaderApple %p", this);
}
In the demo code of cocos2d-x: DownloaderTest.cpp they use:
std::unique_ptr<network::Downloader> downloader;
downloader.reset(new cocos2d::network::Downloader());
instead of:
auto downloader = new Downloader();
It looks like you are building this network code as part of your scene tree. If you do a replaceScene/popScene...() call, while the async network software is running in the background, this will cause the callback to disappear (the scene will be deleted from the scene-stack) and you will get a SEGFAULT from this.
If this is the way you've coded it, then you might want to extract the network code to a global object (singleton) where you queue the requests and then grab them off the internet saving the results in the global-object's output queue (or their name and location) and then let the scene code check to see if the avatar has been received yet by inquiring on the global-object and loading the avatar sprite at this point.
Note, this may be an intermittent problem which depends on the speed of your machine and the network so it may not be triggered consistently.
Another solution ...
Or you could just set your function pointers to nullptr in your PlayerIcon::~PlayerIcon() (destructor):
downloader->setOnFileTaskSuccess(nullptr);
downloader->setOnTaskProgress(nullptr);
Then there will be no attempt to call your callback functions and the SEGFAULT will be avoided (Hopefully).

SHGetFileInfo doesn't return correct handle to icon

I'm using SHGetFileInfo function for getting icons for folders and different file types. According to MSDN call of this function should be done from background thread and before call Component Object Model (COM) must be initialized with CoInitialize or OleInitialize.
My code looks like this:
public void SetHlinkImage(string path)
{
Shell32.OleInitialize(IntPtr.Zero);
Task task = Task.Factory.StartNew(() => { LoadIcons(path); });
}
private void LoadIcons(string path)
{
image = GetHlinkImage(path);
if (OwnerControl.InvokeRequired)
layout.ModuleControl.BeginInvoke((MethodInvoker)delegate ()
{
Shell32.OleUninitialize();
});
}
public Icon GetHlinkImage(string path)
{
uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_ATTRIBUTES | Shell32.SHGFI_SMALLICON;
Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO();
IntPtr result = Shell32.SHGetFileInfo(path,
Shell32.FILE_ATTRIBUTE_DIRECTORY,
ref shfi,
(uint)Marshal.SizeOf(shfi),
flags);
Icon icon = (Icon)Icon.FromHandle(shfi.hIcon).Clone();
WinApi.DestroyIcon(shfi.hIcon); // cleanup
return icon;
}
Mostly the problem appears after first call of the code and as result I get an exception when I tried to create Icon from icon handle:
System.ArgumentException: Win32 handle that was passed to Icon is not
valid or is the wrong type
And further calls of the code work without problems.
Actually behaviour also somehow depends on the test system. It is hardly possible to reproduce this issue on Windows10 systems but on Windows 7 it happens quite often.
Has anyone experienced this problem?
From comment of Hans Passant:
Calling OleInitialize() is pointless, the CLR already initializes COM before it starts a thread. And it failed, something you cannot see because you are not checking its return value. Not knowing that, it just spirals into undiagnosable misery from there. Yes, more of it on Win7. You must provide an STA thread, if this needs to run in the background then consider this solution.

How to create an actionscript Object in Haxe

I am creating an actionscript video player in Haxe and to avoid the asyncError I am trying to create a custom Object. How do I do this is Haxe?
The client property specifies the object on which callback methods are invoked. The default object is the NetStream object being created. If you set the client property to another object, callback methods will be invoked on that other object.
Here is my code.
public function new()
{
super();
trace("video");
//initialize net stream
nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
buffer_time = 2;
ns.bufferTime = buffer_time;
//Add video to stage
myVideo = new flash.media.Video(640, 360);
addChild(myVideo);
//Add callback method for listeing on NetStream meta data
client = new Dynamic();
ns.client = client;
client.onMetaData = metaDataHandler;
}
public function playVideo(url:String)
{
urlName = new String(url);
myVideo.attachNetStream(ns);
ns.play(urlName);
ns.addEventListener(NetStatusEvent.NET_STATUS, netstat);
}
function netstat(stats:NetStatusEvent)
{
trace(stats.info.code);
}
function metaDataHandler(infoObject:Dynamic)
{
myVideo.width = infoObject.width;
myVideo.height = infoObject.height;
}
You should probably do:
client : Dynamic = {};
Forget the client object; it isn't necessary for playing FLVs or for handling async errors. For that, just add a listener to the NetStream for AsyncErrorEvent.ASYNC_ERROR.
I suggest you add a listener to the NetConnection and the NetStream for NetStatusEvent.NET_STATUS, and then trace out the event.info.code value within the listener.
You should first see the string "NetConnection.Connect.Success" coming from the NetConnection; when you play your video through the NetStream, you should see "NetStream.Play.StreamNotFound" if there's a problem loading the FLV. Otherwise you should see "NetStream.Play.Start".
Unless you're progressively streaming your FLV, you may not see any video playing until the file has finished loading. If the movie file is long, this may explain why your program is running without errors but isn't playing the movie. There are small test FLV files available online that you might wish to use while you track the problem down.
(ActionScript's FLV playback API is bizarre and haXe's documentation is rudimentary, so you're rightfully frustrated.)
This maybe useful... http://code.google.com/p/zpartan/source/browse/zpartan/media/
You can see it being used
http://code.google.com/p/jigsawx/

C# application is closed unexpectedly!

I'm having a very frustrating problem. I have a c# win application. When I have clicked the button, the program closes itself after executed the click event handler. Even if I have debugged the code unfortunately I can't see any error, It just quits the program.
Where am I going wrong?
Here is the Code:
private void btnOpenFolder_Click(object sender, EventArgs e)
{
DialogResult dg = fd1.ShowDialog();
if (dg == DialogResult.OK)
{
lblInput.Text = fd1.SelectedPath;
btnOpenFolder.Enabled = false;
timerCallback = new TimerCallback(tmrQualityEvent);
tmrQuality = new System.Threading.Timer(timerCallback, null, 0, 1000);
Thread qualityThread = new Thread(new ThreadStart(QualityMapOpenFolder));
qualityThread.Start();
QualityMapOpenFolder();
}
}
void QualityMapOpenFolder()
{
fileList.Clear();
string path = lblInput.Text;
if (Directory.Exists(path))
{
foreach (var file in Directory.GetFiles(path))
{
if (Path.GetExtension(file) != ".kml")
{
fileList.Add(file);
}
}
SetProgressBarValue(0);
ChangeFileNameLabel(fileList[0]);
FileName = fileList[0];
}
else
SetText("Please make sure you have correctly set the open folder path!", true);
dataListQuality = GetInputData();
SetText("Calculated Data has been created, please click process files...", false);
SetProcessButtonStatus(true);
}
Attach an event handler to the UnhandledException handler and log it. Should help you to find out why your application is crashing.
Update: Now that you have posted some code:
You seem to update UI elements from another thread which you start. You should access UI components only from the thread on which they were created (usually the main thread). Consider using a BackgroundWorker
You start the QualityMapOpenFolder method on a thread and then you also call it after you started the thread - this seems a bit weird and has probably some unexpected side effects.
The common reason for this kind of behavior is unhandled exception in background thread. To prevent program.
#ChrisWue wrote on how to detect this kind of exceptions.
Also, often Windows Application log provides an insight on unhandled errors.
See here how to prevent killing app in this case.

Resources