在主 ui 线程上处理来自其他线程的太多动画请求 - android
Posted
技术标签:
【中文标题】在主 ui 线程上处理来自其他线程的太多动画请求 - android【英文标题】:handling too many requests of animation on the main ui thread from other threads - android 【发布时间】:2015-04-21 09:21:58 【问题描述】:我正在创建具有太多动画的活动,并且在启动此活动时,logcat 在此活动的生命周期内一次又一次地向我显示此消息:
I/Choreographer﹕ Skipped 36 frames! The application may be doing too much work on its main thread.
所以我在另一个线程中做了很多事情,但在主 UI 线程上仍然有大量访问。此外,动画在一些高分辨率设备上变得非常缓慢
有什么可能的解决方案来处理这个问题?
更新:添加代码
所以这里是显示视图的代码(这是 6 个图像按钮),
private void setupAnimationForAllViews(ArrayList<View> listOfViews,
int animationId,
final boolean isAppearing)
int startDelay = mDelay; // milliseconds
int numberOfViews = listOfViews.size();
for (int i = 0; i < numberOfViews; i++)
final Animation animator = AnimationUtils.loadAnimation(mContext, animationId);
animator.setStartOffset(startDelay);
startDelay += mOffSet; // every view will start after 100 milliseconds from the other
final View currentView = listOfViews.get(i);
final int indexOfCurrentCheckedItem = i;
mMainUIThreadHandler.post(new Runnable()
@Override
public void run()
currentView.startAnimation(animator);
);
我在这样的单独线程中触发它:
new Thread(new Runnable()
@Override
public void run()
setupAnimationForAllViews(tempListOfViews,
animationId, isAppearing);
).start();
在同一个活动中,我有 Ken Burns View,它在 2 张图像上实现了 ken Burns 效果,此 kenBurnsView 的代码在此链接中:KenBurnsView
所以这是主要的活动 xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="#111"
android:orientation="vertical"
android:weightSum="7">
<FrameLayout
android:id="@+id/header"
android:layout_weight="6"
android:layout_
android:layout_>
<yasinseyhan.com.yukselirgroup.Activities.GeneralActivities.KenBurnsView
android:id="@+id/header_picture"
android:layout_
android:layout_
android:src="@drawable/uphill2" />
<ImageView
android:id="@+id/header_logo"
android:layout_
android:layout_
android:layout_gravity="center"
android:src="@drawable/header_white" />
</FrameLayout>
<LinearLayout
android:id="@+id/dsd"
android:layout_
android:layout_
android:layout_gravity="bottom"
android:layout_weight="1"
android:weightSum="3"
android:orientation="vertical"
>
<View
android:layout_
android:layout_
android:background="@android:color/white"
android:layout_weight="0.5"/>
<LinearLayout
android:id="@+id/linearLayout"
android:layout_
android:layout_
android:layout_weight="1"
android:orientation="horizontal">
<ImageView
android:id="@+id/btnKur"
android:layout_
android:layout_
android:layout_margin="1dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/btn_kurumsal_selector"/>
<ImageView
android:id="@+id/btnGroup"
android:layout_
android:layout_
android:layout_margin="1dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/btn_groups"/>
<ImageView
android:id="@+id/btnSektorelFaa"
android:layout_
android:layout_
android:layout_margin="1dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/btn_sektorel_selector"/>
</LinearLayout>
<LinearLayout
android:id="@+id/secondLineLinearLayout"
android:layout_
android:layout_
android:layout_weight="1"
android:orientation="horizontal">
<ImageView
android:id="@+id/btnInsanKayna"
android:layout_
android:layout_
android:layout_margin="1dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/btn_ik_selector"/>
<ImageView
android:id="@+id/btnGale"
android:layout_
android:layout_
android:layout_margin="1dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/btn_galeri_selector"/>
<ImageView
android:id="@+id/btnIlet"
android:layout_
android:layout_
android:layout_margin="1dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/btn_iletisim_selector"/>
</LinearLayout>
<View
android:layout_
android:layout_
android:layout_weight="0.5"
android:background="@android:color/white"/>
</LinearLayout>
</LinearLayout>
这是主要的活动java部分:
public class MainActivity extends Activity
//Buttons in the MainActivity
AnimationHelper animationHelper;
ArrayList<View> listOfButtons;
Handler mUIThreadHandler = new Handler();
private final int hideOnClickAnimation = R.anim.fade_out;
private final int displayAnimation = R.anim.test_anim;
//For Kenburns View with multible images
private KenBurnsView mKenBurnsView;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
initAnimation();
init();
// for testing, we may put those in initAnimation()
animationHelper.setDelay(100);
animationHelper.setOffSet(50);
mKenBurnsView.setResourceIds(R.drawable.test16, R.drawable.uphill2);
private void initAnimation()
//Adding OnClickListeners to the Buttons in the MainActivity - End
// The order is important here
listOfButtons = new ArrayList<>();
listOfButtons.add(btnGroupSirketleri);
listOfButtons.add(btnGale);
listOfButtons.add(btnSektorelFaa);
listOfButtons.add(btnKur);
listOfButtons.add(btnInsanKayna);
listOfButtons.add(btnIlet);
// Adding Animation
animationHelper = new AnimationHelper(listOfButtons, this, mUIThreadHandler);
private void initUI()
//initializing the buttons in the mainactivity
btnKur = (ImageView) findViewById(R.id.btnKur);
btnGroup = (ImageView) findViewById(R.id.btnGroup);
btnSektorelFaa = (ImageView) findViewById(R.id.btnSektorelFaa);
btnInsanKayna = (ImageView) findViewById(R.id.btnInsanKayna);
btnGale = (ImageView) findViewById(R.id.btnGale);
btnIlet = (ImageView) findViewById(R.id.btnIlet);
// KenBurns View
mKenBurnsView = (KenBurnsView) findViewById(R.id.header_picture);
private void init()
//Adding OnClickListeners to the Buttons in the MainActivity - Start
btnKur.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
animationHelper.hideViewsWithClickedView(hideOnClickAnimation, v);
);
btnGroup.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
animationHelper.hideViewsWithClickedView(hideOnClickAnimation, v);
);
btnSektorelFaa.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
animationHelper.hideViewsWithClickedView(hideOnClickAnimation, v);
);
btnInsanKayna.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
animationHelper.hideViewsWithClickedView(hideOnClickAnimation, v);
);
btnGale.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
animationHelper.hideViewsWithClickedView(hideOnClickAnimation, v);
);
btnIlet.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
animationHelper.hideViewsWithClickedView(hideOnClickAnimation, v);
);
@Override
protected void onResume()
super.onResume();
animationHelper.displayViews(displayAnimation, new IDoOnEndOfWholeAnimation()
@Override
public void doIt()
if (!mKenBurnsView.isAnimating)
mKenBurnsView.startKenBurnsAnimation();
);
@Override
protected void onPause()
super.onPause();
if (mKenBurnsView.isAnimating)
mKenBurnsView.stopKenBurnsAnimation();
【问题讨论】:
您使用的是哪种类型的动画?显示您的代码。 好的,我将发布我的部分代码,我为这些功能使用动画,(按顺序显示许多视图,KenBurnsView,并隐藏许多视图)。 @PiyushGupta 我添加了代码 您的新线程将以与主线程相同的优先级运行(因为它从父线程继承其优先级)。可能这不是您的问题的原因,但在 Android 中,最好将线程的优先级始终设置为 Thread.MIN_PRIORITY 或 android.os.Process.THREAD_PRIORITY_BACKGROUND @Stevie 问题可能是我在 xml 中设置的权重吗?我已经根据重量创建了整个 xml,以使其适用于所有屏幕尺寸 【参考方案1】:我减小了 Kenburns 和按钮背景的图像尺寸和分辨率,以使其顺利运行。玩线程并没有解决我的滞后问题。
【讨论】:
以上是关于在主 ui 线程上处理来自其他线程的太多动画请求 - android的主要内容,如果未能解决你的问题,请参考以下文章
核心数据使用完成处理程序执行获取请求或在主线程以外的其他线程中执行
如何停止主 ui 线程,直到我得到来自 http 请求的响应