MainActivityには、TextView:textV1があります。 MainActivityには、そのテキストビューを更新するメソッドもあります。
public void updateTheTextView(final String t) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
TextView textV1 = (TextView) findViewById(R.id.textV1);
textV1.setText(t);
}
});
}
BroadcasrReceiverで、MainActivityのtextV1のテキストを更新する必要があります。
public class NotifAlarm extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// other things done here like notification
// NEED TO UPDATE TEXTV1 IN MAINACTIVITY HERE
}
}
これはどのように行うことができますか? BroadcastReceiverはサービスから実行されます。このコードは変更できません。 onReceive()からMainActivityのtextV1にアクセスして変更できますか?私は多くのことを試みましたが、すべて失敗しました。
MainActivity
で、以下のようにMainActivity
クラスの変数を初期化します。
public class MainActivity extends Activity {
private static MainActivity ins;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ins = this;
}
public static MainActivity getInstace(){
return ins;
}
public void updateTheTextView(final String t) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
TextView textV1 = (TextView) findViewById(R.id.textV1);
textV1.setText(t);
}
});
}
}
public class NotifAlarm extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
try {
MainActivity .getInstace().updateTheTextView("String");
} catch (Exception e) {
}
}
}
クラスのインスタンスを作成し、TextView値を変更する関数に値を渡します。次の手順に従ってください:BroadcastReceiver overRide onReceiveメソッドで、これらの行を貼り付けるか、必要に応じてテーマを変更します
private Handler handler = new Handler(); // Handler used to execute code on the UI thread
// Post the UI updating code to our Handler
handler.post(new Runnable() {
@Override
public void run() {
//Toast.makeText(context, "Toast from broadcast receiver", Toast.LENGTH_SHORT).show();
YourActivityToUpdate.updateTheTextView(message);
YourActivityToUpdateinst = YourActivityToUpdate.instance();
if(inst != null) { // your activity can be seen, and you can update it's context
inst.updateTheTextView(message);
}
}
});
次に、YourActivityToUpdateクラスのupdateTheTextViewとinstについて説明します。これらの行を貼り付けてください。
private static SignUpVerify mInst;
public static SignUpVerify instance() {
return mInst;
}
@Override
public void onStart() {
super.onStart();
mInst = this;
}
@Override
public void onStop() {
super.onStop();
mInst = null;
}
これは、YourActivityToUpdateクラスに配置する必要があるupdateTheTextViewメソッドです。
public void updateTheTextView(final String verifyCodeValue) {
Log.i("verifyCodeValue", verifyCodeValue);
YourTextViewToUpdate.setText(verifyCodeValue);
}
"kevin-lynx"のおかげで、これはより良い方法だと思います
誰かがこの正確な解決策を探しているが、Kotlinである場合は、次のようにします。
class MainActivity : AppCompatActivity() {
companion object {
var ins: MainActivity? = null
fun getInstance(): MainActivity? {
return ins
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ins = this
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ins = this;
}
fun updateTheTextView(t: String) {
[email protected] {
val textV1 = findViewById<TextView>(R.id.textV1)
textV1.text = t
}
}
}
class NotifAlarm : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
try {
MainActivity.getInstance()?.updateTheTextView("The String")
} catch (e: Exception) {
}
}
}
この状況に対処する別の方法は、インターフェイスを使用することです。このアプローチを使用する利点について説明しますが、最初にその方法を見てみましょう。
次の手順を実行します:
1)インターフェースを作成する
public interface MyBroadcastListener{
public void doSomething(String result);
}
2)BroadCastReceiverでリスナーを初期化します
public class NotifAlarm extends BroadcastReceiver {
private MyBroadcastListener listener;
@Override
public void onReceive(Context context, Intent intent) {
listener = (MyBroadcastListener)context;
// other things done here like notification
// NUPDATE TEXTV1 IN MAINACTIVITY HERE
listener.doSomething("Some Result");
}
}
)アクティビティにインターフェースを実装し、メソッドをオーバーライドします
public YourActivity extends AppCompatActivity implements MyBroadcastListener{
// Your Activity code
public void updateTheTextView(String t) {
TextView textV1 = (TextView) findViewById(R.id.textV1);
textV1.setText(t);
}
@Override
public void doSomething(String result){
updateTheTextView(result); // Calling method from Interface
}
}
インターフェイスアプローチを使用すると、BroadcastReceiverはアクティビティから独立します。将来、BroadcastReceiverから結果を取得し、その結果でDetailActivityを開始する別のアクティビティでこのBroadCastReceiverを使用するとします。これは完全に異なるタスクですが、BroadcastReceiver内のコードを変更せずに同じBroadcastReceiverを使用します。
それを行う方法は?
アクティビティにインターフェースを実装し、メソッドをオーバーライドします。それでおしまい!
public ListActivity extends AppCompatActivity implements MyBroadcastListener{
// Your Activity code
public void startDetailActivity(String title) {
Intent i = new Intent(ListActivity,this, DetailActivity.class);
i.putExtra("Title", title);
startActivity(i);
}
@Override
public void doSomething(String result){
startDetailActivity(String title); // Calling method from Interface
}
}
あなたのbroadcastreceiverクラスでブロードキャストを送信します
_public class mybroadcaster extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
context.sendBroadcast(new Intent("updatetext"));
}
}
_
アクティビティでbroadcastreceiverを登録して呼び出し、onReceive
で作業を行い、onDestroy()
でブロードキャスターの登録を解除します。
_public class MyActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(broadcastReceiver, new IntentFilter("updatetext"));
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// do your work here
}
};
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
}
}
_