Android/Java:使用接口 [duplicate] 编辑来自另一个类/线程的文本视图

Android/Java: Edit textview from another class/thread with interface [duplicate]

提问人:NikolaN 提问时间:7/2/2023 最后编辑:NikolaN 更新时间:8/21/2023 访问量:82

问:

我想编辑 MainActivity 类中的文本视图文本,并放置一个连接到接口的函数,然后该函数进入另一个名为 JobService 的类(用于发送带有线程的类)。但是我在构造函数部分遇到错误,它暗示了 myCallback 部分的空指针异常。即使我给字符串里面有代码(timestampJob),它也会进入空指针异常。

//MainActivity class

public class MainActivity extends AppCompatActivity implements MyCallback

    TextView timestampMails;

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    timestampMails = (TextView) findViewById(R.id.timeStampMainMails);

    }

    //function for changeing the textview connected with interface to JobService class
    public void setTimestampMain(String time){
        timestampMails.setText(time);
    }

//Interface class

public interface MyCallback {
    public void setTimestampMain(String myString);
}

//JobService class

public class JobService extends android.app.job.JobService {

    //interface call
    MyCallback myCallback = null;
    //constructor
    public JobService(MyCallback callback){
        this.myCallback = callback;
    }
    public void timeStampJob(String time){
        //HERE IS THE EXCEPTION (I think)
        if(myCallback != null){
            myCallback.setTimestampMain(time);
        }
    }

    @Override
    public boolean onStartJob(JobParameters params) {
        Log.d(TAG, "Job started");
        doBackgroundWork(params);

        return true;
    }

    private void doBackgroundWork(JobParameters params) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0; i<1; i++){

                    //get device time function and populate function with that string
                    String deviceTime = new     SimpleDateFormat("HH:mm").format(Calendar.getInstance().getTime());
                    timeStampJob(deviceTime);

                 
                    if(jobCancelled){
                        return;
                    }

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                Log.d(TAG, "Job finished:");
                jobFinished(params, false);
            }
        }).start();

    }

    @Override
    public boolean onStopJob(JobParameters params) {
        Log.d(TAG, "Job cancelled before completion");
        jobCancelled = true;

        return true;
    }

Process: com.example.gmailemailsolution, PID: 3944
java.lang.RuntimeException: Unable to instantiate service
com.example.gmailemailsolution.JobService: java.lang.InstantiationException:
java.lang.Class<com.example.gmailemailsolution.JobService> has no zero
argument constructor (HERE)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3268)
at android.app.ActivityThread.-wrap5(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1608)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:173)
at android.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:938)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:828)
Caused by: java.lang.InstantiationException:
java.lang.Class<com.example.gmailemailsolution.JobService> has no zero
argument constructor (HERE)
at java.lang.Class.newInstance(Native Method)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3265)
at android.app.ActivityThread.-wrap5(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1608)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:173)
at android.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:938)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:828) 

尝试了接口类,用构造函数调用它并使 textview 静态,但没有让它工作。

Java Android 函数 构造函数 接口

评论

0赞 Sametcey 7/2/2023
嗨,您是否尝试在 UI 线程中运行代码?您可以使用 Handler 来完成。
0赞 NikolaN 7/2/2023
@Sametcey嗯,我没有尝试过。你认为这个异常是因为专用线程而引发的吗?
0赞 Sametcey 7/2/2023
我写一个答案,请试试。
1赞 Tyler V 7/2/2023
您发布的错误是因为 JobService 类需要零参数构造函数,但您的类没有。看看这个问题,了解如何实现它,但根据你实际想在服务中做什么,这可能有点矫枉过正。如果您还在问题中包括为什么首先需要服务以及将对其进行哪些工作,您将获得更好的答案。
2赞 Gabe Sechan 7/2/2023
您永远不会从 JobService 更新 UI。服务是单独的上下文,服务不应无法访问活动。如果您设法找到某种方法,这样做是 100% 的内存泄漏。JobService 旨在与 JobScheduler 一起使用,JobScheduler 是一种用于安排未来要完成的工作的机制。不能保证您的活动在触发时正在运行,事实上,使用它的通常原因是您的活动预计不会运行。你需要退后一步,描述你实际尝试用这段代码做什么,并学习正确的方法。

答:

-1赞 Sametcey 7/2/2023 #1

您还可以通过以下方式从后台线程更新 UI 线程:

Handler handler = new Handler();

//below piece of code is written in function of class that extends from AsyncTask

handler.post(new Runnable() {
    @Override
    public void run() {
        textView.setText(stringBuilder);
    }
});

必须将视图对象传递给运行处理程序的类。

评论

0赞 NikolaN 7/2/2023
我不确定如何在我的代码中实现它。
0赞 Ryan M 8/22/2023
例如,这无法解释将 由于使用了已弃用的零参数构造函数,因此将Handler handler = new Handler();