Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Used in ViewPager fragments randomly crashes the app (NullPointerException: Attempt to invoke virtual method void View.sendAccessibilityEventUnchecked) #6

Open
Jars-of-jam-Scheduler opened this issue Apr 6, 2020 · 2 comments

Comments

@Jars-of-jam-Scheduler
Copy link

Jars-of-jam-Scheduler commented Apr 6, 2020

Hello,

I am using your library in a project. I am facing an issue that makes the app randomly crash when your library is used within a fragment within a ViewPager. I have isolated the part of the library that leads to the bug. Full minimal and executable sources and more informations are available in this StackOverflow question: https://stackoverflow.com/questions/61061130/textview-in-viewpager-fragments-randomly-crashes-the-app-nullpointerexception-a .

Could you please take a look at this?

I thank you in advance,
Best regards,


Edit

I think I've found a solution: using runOnUiThread in the following class (changes were added, you can compare it to your own class, I didn't want to fork/do a pull request just for that .......... also, you can find a bit more info in my Stackoverlow Question, which I linked above):

package libs.AutoScrollTextView;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatTextView;

import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 跑马灯效果TextView
 *
 * @author haohao on 2017/9/21 下午 02:33
 * @version v1.0
 */
public class MarqueeTextView extends AppCompatTextView {

    private int currentScrollPos = 0;
    //速度
    private int speed = 6;
    // 文字宽度
    private int textWidth = -1;
    //是否计算了宽度
    private volatile boolean isMeasured = false;
    //是否完成移动
    private volatile boolean flag = false;
    //是否停止移动
    private volatile boolean isStop = false;

    private IMarqueeListener marqueeListener;
    private Future future;

    ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);

    final TimerTask task = new TimerTask() {
        @Override
        public void run() {
            ((AppCompatActivity) getContext()).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (textWidth == -1) {
                        postInvalidate();
                        return;
                    }
                    if (isStop) {
                        return;
                    }
                    if (!flag && currentScrollPos >= textWidth - getWidth()) {
                        //currentScrollPos = -getWidth();
                        task.cancel();
                        flag = true;
                        if (marqueeListener != null) {
                            marqueeListener.onFinish();
                        }
                    }

                    if (!flag) {
                        currentScrollPos += 1;
                        scrollTo(currentScrollPos, 0);
                    }
                }
            });
        }
    };

    public MarqueeTextView(Context context) {
        super(context);
        init();
    }

    public MarqueeTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MarqueeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setSingleLine();
    }

    public void startScroll() {
        reset();
        stopFuture();
        future = pool.scheduleAtFixedRate(task, 0, speed, TimeUnit.MILLISECONDS);
        //removeCallbacks(runable);
        //post(runable);
    }

    public void postStartScroll(int delay) {
        reset();
        stopFuture();
        future = pool.scheduleAtFixedRate(task, delay, speed, TimeUnit.MILLISECONDS);
        //removeCallbacks(runable);
        //postDelayed(runable, delay);
    }

    public void stopScroll() {
        isStop = true;
        stopFuture();
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public void setMarqueeListener(IMarqueeListener marqueeListener) {
        this.marqueeListener = marqueeListener;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (!isMeasured) {
            getTextWidth();
            isMeasured = true;
        }
    }

    private void getTextWidth() {
        Paint paint = this.getPaint();
        String str = this.getText().toString();
        if (TextUtils.isEmpty(str)) {
            textWidth = 0;
        }
        textWidth = (int) paint.measureText(str);
    }

    public void reset() {
        flag = false;
        isStop = false;
        currentScrollPos = 0;
        scrollTo(currentScrollPos, 0);
    }

    public void setText(String str) {
        super.setText(str);
        isMeasured = false;
        invalidate();
    }

    private synchronized void stopFuture() {
        if (future != null && !future.isCancelled()) {
            future.cancel(true);
        }
        if (task != null) {
            task.cancel();
        }
    }
}
@ronghao
Copy link
Owner

ronghao commented Apr 9, 2020

你好,
看到你的问题了,很高兴你能提出问题。
1、根据你的提示和stackoverflow的问题描述,我写了测试代码,自测不会出现崩溃问题。如果你有时间,可以将我的整个工程clone下来,运行app工程,里面有示例代码。
2、根据你添加的代码,我怀疑是子线程处理UI导致系统崩溃问题。
3、我临时加上了MarqueeTextViewForViewPager,你可以先暂用这个类

@protectedMan
Copy link

很不错的东西

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants