【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
答案 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;
}
}
推荐阅读
- 没有声明Xamarin.Android Button Border
- 如何从xamarin表单应用程序中的PCL项目访问android原生布局文件()
- 在Xamarin.Android中将Keycode转换为char
- 获取ObtainStyledAttributes以在Android的xamarin中正常工作
- Xamarin.Android.Support.Fragment,Version = 1.0.0.0,Culture = neutral,PublicKeyToken ='。也许它在Mono
- ObjectMapper如果某些字段无法转换为对象的默认值
- 如何在Symfony 3中使用纯PHP编译LESS
- 如何使用Smarty循环显示字母和数字的列表
- 如何在Silex中将PHP用作模板引擎而不是Twig