2016-07-17 12 views
11

संपादित करें: नमूना परियोजना दर्शाता है कि दुर्घटना यहां पाया जा सकता: https://github.com/rringham/brokenazurexamforms - आप में अपने स्वयं के Azure अनुप्रयोग सेवा URL निर्धारित करने की आवश्यकता:Azure MobileServiceClient LoginAsync() के बाद Navigation.PushAsync क्रैश क्यों होता है?

  • src/BrokenAzureForms/Droid/सेवा/उपयोगकर्ता/DroidUserService .cs
  • src/BrokenAzureForms/iOS/सेवा/उपयोगकर्ता/IosUserService.cs

मैं Xamarin फार्म के एंड्रॉयड पर Navigation.PushAsync() दुर्घटना दिखाई दे रही है जब मैं के बाद यह उपयोग करने के लिए Azure MobileServiceClient को प्रमाणित करने का प्रयास। यह क्रैश एंड्रॉइड के लिए अलग है - यह आईओएस पर नहीं होता है।

यहाँ सेटअप है - मैं अपने मुख्य अनुप्रयोग पृष्ठ के रूप में एक बुनियादी NavigationPage मिल गया है:

MainPage = new NavigationPage(new LoginPage()); 

पर मेरी LoginPage, मैं एक DependencyService -injected वर्ग कि मेरे Android परियोजना में प्रमाणीकरण प्रदर्शन का उपयोग करके प्रमाणित:

private async void OnMicrosoftAccountTapped(object sender, EventArgs args) 
{ 
    IUserService userService = DependencyService.Get<IUserService>(); 
    bool authenticated = await userService.LoginWithAzureAD(); 
    if (authenticated) 
    { 
     await Navigation.PushAsync(new HomePage(), false); 
    } 
} 

IUserService की मेरे Android कार्यान्वयन में, मैं यह कर (काफी वास्तव में क्या Azure/Xamarin फॉर्म्स ट्यूटोरियल दिखाने):

public async Task<bool> LoginWithAzureAD() 
{ 
    try 
    { 
     _user = await _client.LoginAsync(Xamarin.Forms.Forms.Context, MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory); 
    } 
    catch (Exception) 
    { 
     return false; 
    } 

    return true; 
} 

यहां चीजें अलग-अलग होती हैं। जब LoginWithAzureAD() किया जाता है, तो नियंत्रण OnMicrosoftAccountTapped() में फिर से शुरू होता है; हम तो Navigation.PushAsync(), और उछाल कॉल करने के लिए जाना - पर जाने के लिए ऐप्लिकेशन क्रैश, बहुत कम विस्तार के साथ:

MobileServiceClient/Navigation crash

सभी मुझे लगता है कि कर सकते हैं

कि Azure MobileServiceClient कुछ सुंदर Xamarin.Forms.Forms.Context साथ फंकी कर रही है आंतरिक रूप से, क्योंकि अगर है मैं await userService.LoginWithAzureAD() पर कॉल को हटाता हूं, Navigation.PushAsync() पर कॉल कोई समस्या नहीं है। MobileServiceClient में कुछ तो टूटा हुआ है, या Xamarin फॉर्म में कुछ तोड़ रहा है।

कोई भी इस तरह कुछ देखता है?

MainActivity.cs में:

Context _context; 

public void Initialize(Context context) 
{ 
    this._context = context; 
} 

public async Task LoginAsync(MobileServiceClient client) 
{ 
    await client.LoginAsync(this._context, MobileServiceAuthenticationProvider.whatever); 
} 

मैं:

// Initialize for Azure Mobile Apps 
Microsoft.WindowsAzure.MobileServices.CurrentPlatform.Init(); 

// Initialize for Xamarin Forms 
global::Xamarin.Forms.Forms.Init(this, savedInstanceState); 

// Initialize for Login Provider 
var lp = (DroidLoginProvider)DependencyService.Get<ILoginProvider>(); 
lp.Initialize(this); 

फिर, मेरी DroidLoginProvider कक्षा में, मैं तो निम्न कार्य करें

+0

हाय @Rob Ringham, तो आप इस में सॉर्ट करने के लिए प्रबंधन किया समाप्त? यह वही समस्या है जिसे मैं इस समय सामना कर रहा हूं और इसे उसी कॉल पर दबा दिया था जैसा आपने किया था। धन्यवाद। –

उत्तर

4

जब मैं ऐसा करते हैं, मैं निम्नलिखित का उपयोग मेरे साझा प्रोजेक्ट में सिंगलटन रैपर से LoginAsync को कॉल करें। यह महत्वपूर्ण है कि यह सिंगलटन है क्योंकि किसी प्रोजेक्ट में केवल एक मोबाइल सेवा क्लाइंट होना चाहिए - प्रमाणीकरण MobileServiceClient.CurrentUser प्रॉपर्टी में संग्रहीत है और केवल वर्तमान क्लाइंट पर सेट है।

आप इस तर्क यहाँ के साथ एक काम कर परियोजना देख सकते हैं: https://github.com/adrianhall/30-days-of-zumo-v2/tree/master/file-upload

+0

धन्यवाद एड्रियन - मैंने यह कोशिश की है, विशेष रूप से मेनएक्टिविटी में एज़ूर मोबाइल ऐप के लिए प्रारंभिक कॉल जोड़ना, साथ ही मुख्य लॉगिन से मेरे लॉगिन प्रदाता पर एंड्रॉइड संदर्भ को कैशिंग करना; मैंने अपने गिट रेपो में कोड अपडेट किया है ताकि यह आपके द्वारा सुझाए जा रहे कार्यों के बराबर प्रभावी ढंग से कार्यक्षमता हो, लेकिन दुर्भाग्यवश मुझे अभी भी दुर्घटना दिखाई दे रही है (मैं सिंगलटन दृष्टिकोण आरई: मोबाइल सेवा क्लाइंट का भी पालन करता हूं)। मैं आपकी नमूना परियोजना को एक भंवर दूंगा और देखता हूं कि यह काम करता है! –

+0

इस पर अंतिम टिप्पणी - मैं अपनी परियोजनाओं में एक्समरिन फॉर्म v2.3.x का उपयोग कर रहा हूं। बाद का संस्करण है, लेकिन मुझे एंड्रॉइड पर वैध संकलन प्राप्त करने के लिए सही संयोजन प्राप्त करने में समस्याएं हैं। –

+0

बस एक एफवाईआई के रूप में, मैं अभी सिंगलेट्स के बारे में पढ़ रहा हूं, और इसे एमएसडीएन पर पाया: "[सिंगलटन] कार्यान्वयन का मुख्य नुकसान यह है कि यह बहुप्रचारित वातावरण के लिए सुरक्षित नहीं है। अगर अलग धागे निष्पादन एक ही समय में इंस्टेंस प्रॉपर्टी विधि दर्ज करें, और अधिक कि सिंगलटन ऑब्जेक्ट का एक उदाहरण बनाया जा सकता है। " (Https://msdn.microsoft.com/en-us/library/ff650316.aspx से लिया गया) –

4

मुझे लगता है कि लॉगिन समस्या ओर्थोगोनल है, और आप एक पृष्ठभूमि धागे से PushAsync कॉल कर रहे हैं। आपको अपने मुख्य थ्रेड से अपनी निर्भरता सेवा विधि पर कॉल का इंतजार करना चाहिए, और उसके बाद PushAsync करें।

यहां एक नमूना है: निर्भरता सेवा में

+0

हम्म, मैं निश्चित रूप से पृष्ठभूमि थ्रेड से 'पुशएसिंक' को नहीं बुला रहा हूं - मेरी लॉगिन WithAzureAD विधि को बटन थ्रेड इवेंट हैंडलर में यूआई थ्रेड पर कॉल किया जाता है, जो बदले में (और उसी थ्रेड पर) 'MobileServiceClient'' LoginAsync' विधि। –

+0

@RobRingham हाँ ऐसा लगता है कि यह अभी भी यूआई थ्रेड होगा। बस इस मुद्दे को अलग करने के लिए, पुशएसिंक कोड को UI पर ले जाने का प्रयास करें और लॉगिन परिणाम का इंतजार करें, और देखें कि अपवाद repros क्या है। –

+0

मुझे यकीन नहीं है कि मैं अनुसरण करता हूं - लॉगिन परिणाम (जो सफलतापूर्वक लौटाता है) के बाद 'पुशएसिंक' कॉल निश्चित रूप से UI थ्रेड पर कॉल किया जा रहा है। मैंने बिना किसी लाभ के 'डिवाइस.बिनिन इनवोकऑनमेन थ्रेड() 'के माध्यम से UI रन लूप को' पुशएसिंक 'पर कॉल करने का भी प्रयास किया है। 'मोबाइल सेवा क्लाइंट' कार्यों के तरीके में कुछ ऐसा है जो एंड्रॉइड पर ज़ैमरिन फॉर्म काम करता है, इसके साथ असंगत प्रतीत होता है; मुझे संदेह है कि यह ज़ैमरिन फॉर्म के भीतर ही एक बग हो सकता है। –

संबंधित मुद्दे