Xamarin.Android WebView App性能问题

【Xamarin.Android WebView App性能问题】君不见长松卧壑困风霜,时来屹立扶明堂。这篇文章主要讲述Xamarin.Android WebView App性能问题相关的知识,希望能为你提供帮助。
我正在开发一个Xamarin.android应用程序,该应用程序正在遭遇性能问题。
该应用包含以下内容:

  • 启动画面延迟1秒。
  • 主要活动包括视图寻呼机,标签式布局,9个片段,广告视图。
  • 每个片段都包含Webview。
主要活动代码:
namespace XXXXX { [Activity(Label = "XXX", Theme = "@style/AppTheme", ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait)] public class MainActivity : AppCompatActivity { AdView adView; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); Toolbar toolbar = FindViewById< Toolbar> (Resource.Id.toolbar); SetSupportActionBar(toolbar); Window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds); var fragments = new Fragment[] { new homeFragment(), new XXXFragment(), new XXXFragment(), new XXXFragment(), new XXXFragment(), new XXXFragment(), new XXXFragment(), new XXXFragment(), newXXXFragment(),}; var titles = CharSequence.ArrayFromStringArray(new[] { "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX" }); var viewPager = FindViewById< ViewPager> (Resource.Id.viewpager); viewPager.OffscreenPageLimit = 1; viewPager.Adapter = new TabsFragmentPagerAdapter(SupportFragmentManager, fragments, titles); // Give the TabLayout the ViewPager var tabLayout = FindViewById< TabLayout> (Resource.Id.sliding_tabs); tabLayout.SetupWithViewPager(viewPager); var isConnected = CrossConnectivity.Current.IsConnected; if (isConnected) {Task.Run(() => { // Log.Debug("TAG", "InstanceID token: " + FirebaseInstanceId.Instance.Token); dddd var instanceid = FirebaseInstanceId.Instance; instanceid.DeleteInstanceId(); Log.Debug("TAG", "{0} {1}", instanceid.Token, instanceid.GetToken(this.GetString(Resource.String.gcm_defaultSenderId), Firebase.Messaging.FirebaseMessaging.InstanceIdScope)); }); FirebaseMessaging.Instance.SubscribeToTopic("custom"); } var iid = "#####"; Android.Gms.Ads.MobileAds.Initialize(ApplicationContext, iid); adView = FindViewById< AdView> (Resource.Id.adView); AdRequest adRequest = new AdRequest.Builder().Build(); adView.LoadAd(adRequest); adView.BringToFront(); } protected override void OnResume() { if (adView != null) adView.Resume(); base.OnResume(); } protected override void OnPause() { if (adView != null) adView.Pause(); base.OnPause(); } public override bool OnCreateOptionsMenu(IMenu menu) { MenuInflater.Inflate(Resource.Menu.top_menus, menu); return base.OnCreateOptionsMenu(menu); } public override bool OnOptionsItemSelected(IMenuItem item) {Intent intent; switch (item.ItemId) {case Resource.Id.nav_feedback:intent = new Intent(this, typeof(Feedback)); StartActivity(intent); return true; case Resource.Id.nav_settings: intent = new Intent(this, typeof(Settings)); StartActivity(intent); return true; default: break; }return base.OnOptionsItemSelected(item); }} }

每个片段包含:
namespace XXXXX { public class HomeFragment : Fragment { public ProgressBar progress; public WebView mWebView; public override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Create your fragment here}public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {Viewview = inflater.Inflate(Resource.Layout.HomeFragmentLayout, container, false); mWebView = view.FindViewById< WebView> (Resource.Id.webView1); progress = view.FindViewById< ProgressBar> (Resource.Id.progressBar); progress.Visibility = ViewStates.Visible; mWebView.Settings.DomStorageEnabled = true; mWebView.Settings.javascriptEnabled = true; mWebView.Settings.LoadWithOverviewMode = true; mWebView.Settings.UseWideViewPort = true; mWebView.Settings.SetSupportZoom(false); mWebView.Settings.BuiltInZoomControls = false; mWebView.Settings.SetEnableSmoothTransition(true); mWebView.Settings.SetAppCacheEnabled(true); mWebView.Settings.SetAppCacheMaxSize(1024 * 1024 * 8); mWebView.Settings.SetAppCachePath(Context.CacheDir.ToString()); if (Build.VERSION.SdkInt > = BuildVersionCodes.Kitkat) mWebView.SetLayerType(LayerType.Hardware, null); else mWebView.SetLayerType(LayerType.Software, null); mWebView.LoadUrl("link"); mWebView.SetWebViewClient(new HybridWebViewClient(Context, this)); mWebView.SetWebChromeClient(new WebChromeClient()); if (CrossConnectivity.Current.IsConnected) { mWebView.Settings.CacheMode = CacheModes.Default; mWebView.Reload(); } else { mWebView.Settings.CacheMode = CacheModes.CacheElseNetwork; }return view; }public class HybridWebViewClient : WebViewClient {private Context context; private HomeFragment homeFragment; public HybridWebViewClient(Context context, HomeFragment homeFragment) { this.context = context; this.homeFragment = homeFragment; }public override bool ShouldOverrideUrlLoading(WebView view, string url) { System.Diagnostics.Debug.WriteLine("ShouldOverrideUrlLoading:" + url); if (url.StartsWith("whatsapp:") || url.StartsWith("tel:")) { Intent intent = new Intent(Intent.ActionView, Android.Net.Uri.Parse(url)); context.StartActivity(intent); return true; } else if (url.StartsWith("tohttp:")) { var DetailedNewsIntent = new Intent(context, typeof(DetailedNewsActivity)); DetailedNewsIntent.PutExtra("Url", url); context.StartActivity(DetailedNewsIntent); return true; } else {view.LoadUrl(url); return true; }} public override void OnPageStarted(WebView view, string url, Android.Graphics.Bitmap favicon) {base.OnPageStarted(view, url, favicon); } public override void OnPageFinished(WebView view, string url) {homeFragment.progress.Visibility = ViewStates.Gone; base.OnPageFinished(view, url); } public override void OnReceivedError(WebView view, [GeneratedEnum] ClientError errorCode, string description, string failingUrl) { base.OnReceivedError(view, errorCode, description, failingUrl); }}}}

启动画面:
namespace XXXX { [Activity(Theme = "@style/MyTheme.Splash", NoHistory = true, MainLauncher = true)] public class SplashActivity : Activity { static readonly string TAG = "X:" + typeof(SplashActivity).Name; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Log.Debug(TAG, "SplashActivity.OnCreate"); // Create your application here } protected override void OnResume() { base.OnResume(); Task startupWork = new Task(() => { Log.Debug(TAG, "Performing some startup work that takes a bit of time."); Task.Delay(1000); // Simulate a bit of startup work. Log.Debug(TAG, "Working in the background - important stuff."); }); startupWork.ContinueWith(t => { Log.Debug(TAG, "Work is finished - start Activity1."); StartActivity(new Intent(Application.Context, typeof(MainActivity))); Finish(); }, TaskScheduler.FromCurrentSynchronizationContext()); startupWork.Start(); } } }

现在为了提高性能,我已尝试过以下但性能未受到预期的影响
  • 最小启动延迟(静态应用程序需要花时间进行启动
  • viewPager.OffscreenPageLimit = 1; (从1到9)
  • Adview异步(需要同时)
该应用程序花费大部分时间进行启动活动
  • 我想更快地启动应用程序。
  • 想要在交换片段时保持页面加载。 (目前,页面在淹没时闪烁)
应用环境 -
  • XA Marin.Android 8.0
  • 适用于Xamarin 4.7的Visual Studio工具
  • Visual Studio 15.4.3
  • minSDK API-14
  • 有针对性的SDK API-25
  • 建筑 -armeabi-v7a
套餐 -
  • Plugin.CurrentActivity
  • Plugin.Share
  • Xam.Plugin.Connectivity
  • XA Marin.Android.support.design 25.4.0.2
  • Xamarin.GooglePlayServices.Ads.Lite 42.1021.1
  • Xamarin.Firebase.Messaging 42.1021.1
请任何人知道调整/提示/黑客提高性能请分享。 TIA !!
答案 FragmentStatePagerAdapter如果有大量的页面,比如你的9页,你的TabsFragmentPagerAdapter应该扩展FragmentStatePagerAdapter类。因为当片段对用户不可见时,片段可能被破坏,并且它允许寻呼机保持更少的内存,它将具有比FragmentPagerAdapter更好的性能。您可以通过链接比较它们。两者在使用上都相似。
UserVisibleHint下面是UserVisibleHint的一个简单的片段延迟加载,在你的片段可见之前你不需要加载数据:
public class Fragment1 : Fragment { bool isViewInit; bool isDataLoad; public override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Create your fragment here }public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Use this to return your custom view for this Fragment var view= inflater.Inflate(Resource.Layout.YourFragment, container, false); isViewInit = true; return view; }public override void OnActivityCreated(Bundle savedInstanceState) { base.OnActivityCreated(savedInstanceState); if (UserVisibleHint) { loadData(); }} public override bool UserVisibleHint { get => base.UserVisibleHint; set { base.UserVisibleHint = value; if (UserVisibleHint & & isViewInit & & !isDataLoad) { loadData(); }} }private void loadData() { //load your data here isDataLoad = true; } }


    推荐阅读