我正在使用Android应用程序,但是遇到了一个我似乎找不到答案的问题。我想在类“ TaskHandler”中从方法“运行”(因此从线程中调用)在类“ MainActivity”中调用方法“ updateTime”。
我已经用Google搜索了一个小时左右的答案,访问了多个网站并找到了多个解决方案,但这些解决方案都不适合我。我还曾在LinusTechTips和Corsair不和谐服务器中询问过此问题。
MainActivity类:
package thedutchmc.net.alarm;
import android.os.Bundle;
import android.widget.EditText;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.time.LocalTime;
public class MainActivity extends AppCompatActivity {
public static String alarmTime;
public static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);
public static boolean alarmBool = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView mTextView = (TextView) findViewById(R.id.currentTime);
mTextView.setText("Current Time: ");
Main.scheduler.scheduleAtFixedRate(new TaskHandler(), 1, 1, TimeUnit.SECONDS);
}
public void onSubmit(View v){
System.out.println("Submit!");
EditText alarmTimeEditText = (EditText) findViewById(R.id.setAlarmTime);
alarmTime = alarmTimeEditText.getText().toString();
System.out.println("MainActivity (alarmTime): " + alarmTime);
alarmBool = true;
}
public void updateTime() {
TextView seeTime = (TextView) findViewById(R.id.currentTime);
seeTime.setText(LocalTime.now().toString());
}
}
TaskHandler类:
package thedutchmc.net.alarm;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class TaskHandler implements Runnable {
final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm");
public static boolean isRinging = false;
private String alarmTime;
public static final MainActivity activity = new MainActivity();
@Override
public void run() {
activity.updateTime();
if (checkAlarmBool()) {
System.out.println("Bool true! Alarm!");
Main.alarm.set(false);
Main.alarm.ringAlarm();
}
}
boolean checkAlarmBool() {
if (MainActivity.alarmBool && !isRinging) {
String lTime = LocalTime.now().format(dtf);
System.out.println("TaskHandler alarmTime: " + MainActivity.alarmTime);
System.out.println("TaskHandler LocalTime: " + lTime);
if(lTime.equalsIgnoreCase(MainActivity.alarmTime)) {
isRinging = true;
return true;
} else {
return false;
}
} else {
return false;
}
}
我希望有人可以帮助我:)
答案 0 :(得分:0)
您不能直接在活动本身之外访问活动的方法。建议在组件之间进行通信的方法是使用Broadcasts。
由于可以从中实例化TaskHandler,因此您可以直接访问您的Activity。您可以只在TaskHandler的构造函数中传递Activity(并将其保存为TaskHandler中的全局变量),但是如果该Activity在TaskHandler执行之前完成,则可能会导致崩溃。
向TaskHandler的构造函数添加上下文:
private Context context;
public TaskHandler(Context context) {
this.context = context;
}
并使用实例化TaskHandler
new TaskHandler(getApplicationContext());
您将能够发送广播,然后可以在您的活动中注册的BroadcastReceiver中接收广播(请阅读链接以获取有关BroadcastReceivers等的详细信息)。
将Context
替换为MainActivity
,将getApplicationContext()
替换为this
,您可以直接调用所需的方法,但这会导致崩溃,这只会如果TaskHandler仅在MainActivity内部使用,则可以正常工作。
如果仅在MainActivity内部使用它,只需将其设为内部类,然后就可以直接调用该方法,而无需任何引用。
无论您做什么,都无法自己创建Activity类的新实例并期望它们能正常工作。
答案 1 :(得分:0)
使用广播。 在您的TaskHandler类中,从“运行”方法内部,发送广播:
Intent i = new Intent("run_method");
sendBroadcast(i);
在您的MainActivity类的onResume()中,注册广播接收器:
private BroadcastReceiver receiver;
if (receiver == null){
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateTime();
}
};
}
registerReceiver(receiver, new IntentFilter("run_method"));
答案 2 :(得分:0)
使TaskHandler成为MainActivity内部的内部类。然后,您将能够调用updateTime()。并删除该静态最终MainActivity变量,如果TaskHandler在MainActivity内部,则将不需要它。切勿使用新的运算符创建活动。
您可能会遇到的另一件事是,您无法从后台线程更新UI,因此您可能希望在调用updateTime()或在updateTime()内部使用runOnUiThread(Runnable)。