如何将一个类中的值传递到 Android Activity

7

我有一个关于类/任务/活动的新手问题。由于我是从C语言转过来,所以不确定我想要做的是否是一个好方法。

我创建了一个类:

public class UDPServer {

    private MyDatagramReceiver myDatagramReceiver = null;

    private static int MAX_UDP_DATAGRAM_LEN = 1024;
    private static int UDP_SERVER_PORT = 5000;

    public void start() {
        myDatagramReceiver = new MyDatagramReceiver();
        myDatagramReceiver.start();
    }

    public void kill() {
        myDatagramReceiver.kill();
    }

    private class MyDatagramReceiver extends Thread {
        private boolean bKeepRunning = true;
        private String lastMessage = "";

        public void run() {
            String message;
            byte[] lmessage = new byte[MAX_UDP_DATAGRAM_LEN];
            DatagramPacket packet = new DatagramPacket(lmessage, lmessage.length);
            DatagramSocket socket = null;

            try
            {
                socket = new DatagramSocket(UDP_SERVER_PORT);

                while(bKeepRunning)
                {
                    socket.receive(packet);
                    message = new String(lmessage, 0, packet.getLength());
                    lastMessage = message;

                    //Here should call activity method

                });
                }

            }
            catch (Throwable e)
            {
                e.printStackTrace();
            }
            finally
            {
                if (socket != null)
                {
                    socket.close();
                }
            }
        }

        public void kill() {
            bKeepRunning = false;
        }
    }
}

在我的Activity中,我有:

@Override
public void onResume() {
    super.onResume();

    mUDPServer = new UDPServer();
    mUDPServer.start();
}

@Override
public void onPause() {
    super.onPause();

    mUDPServer.kill();
}

现在,每次我收到一个数据包,我希望这个线程/类将接收到的数据包传递给一个活动方法来处理(进行一些计算或更新一些UI等)。但是我不知道如何做到这一点,也许我的方法不正确。我可以将线程代码放在活动中,但这似乎会使代码变得不太可读。
有什么建议吗?
@Anshul Jain 代码更新:
    public class Main_activity extends Activity implements Interface_UDPServer{
    TextView recived_message;

    UDPServer mUDPServer;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        recived_message = (TextView)findViewById(R.id.recived_message);
    }

    @Override
    public void onResume() {
        super.onResume();

        mUDPServer = new UDPServer(this);
        mUDPServer.start();
    }

    @Override
    public void onPause() {
        super.onPause();

        mUDPServer.kill();
    }

    public void sendData(final String str){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                recived_message.setText(str);
            }
        });
    }

}

XML文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_below="@+id/linearLayout"
        android:layout_alignLeft="@+id/linearLayout"
        android:layout_alignStart="@+id/linearLayout">
    <TextView
        android:id="@+id/recived_message"
        android:layout_width="200dp"
        android:layout_height="35dp"
        android:textColor="#444444"
        android:textSize="20dp" />
    </LinearLayout>
</RelativeLayout>
7个回答

9
您可以使用回调函数来实现这个目的。
定义一些接口,例如:
public interface MyCustomInterface(){
    public void sendData(String str);
}

现在让您的Activity实现这个接口。
public class MyActivity implements MyCustomInterface {

@Override
public void sendData(String str){

Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
  @Override
  public void run() {
    recived_message.setText(str);
  }
});
}
}

现在,在UDPServer.java中编写以下代码。
public class UDPServer {

private MyCustomInterface interface;

UDPServer(MyCustomInterface interface){
 this.interface = interface; 
}

}

现在,当您有一些可用的数据,比如一个字符串时,您可以像这样发送它。
interface.sendData(str);

1
我已经尝试了您的代码并进行了更正:将 "public class MyCustomInterface(){" 更改为 "public interface MyCustomInterface(){",并将 "private MyCustomInterface interface;" 更改为 "private MyCustomInterface otherNameInterface;",因为 Android IDE 将接口名称视为定义。 - Singee
仍然不行,我已经调试过了,可以正确地接收数据包并传输到Activity。但是当我运行一个例子“recived_message.setText(str);”时,它不会更新我的ViewText。我还尝试了使用runOnUiThread(new Runnable() { @Override public void run() { recived_message.setText(str); } }); 但是没有任何效果。 - Singee
如果您能够获取UI活动数据,那么TextView没有更新的原因就不存在了。您一定是漏掉了什么。您能否提供最新的代码? - thedarkpassenger
我已经更新了sendData函数内的代码,请查看它是否有效。 - thedarkpassenger
1
请阅读这个回答:https://dev59.com/fGYr5IYBdhLWcg3wE2Sz。如果您的问题得到解决,请接受这个答案。 - thedarkpassenger
显示剩余2条评论

2

你有一个A活动和一个B活动,当你在B活动完成操作后,需要它影响到A活动,当你回到A活动时。

  1. Create an Instance Class and a method that u type u need, let's say;

    public interface SelectedBirthday {
    
        void onSelectedData(String date);
    }
    
  2. Now we are on B side, Create an instance of your Interface Class

    private SelectedBirthday mCallback;
    
  3. Override

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    
        try {
            mCallback = (SelectedBirthday) activity;
        } catch (ClassCastException e) {
            Log.d("MyDialog", "Activity doesn't implement the ISelectedData interface");
        }
    }
    
  4. Now upload the value you needed

    String userBirth = (day + " " + month + " " + year);
    
    mCallback.onSelectedData(userBirth);
    
  5. Ok let's go to A side

实现我们的接口类

implements SelectedBirthday

它会警告你使用了它的方法,而你已经实现了它

     @Override
        public void onSelectedData(String date) {
            if (!date.equals("")) {
                txt_poup_age.setText(date);
//now you are free to do what you want with the value you received automaticaly
            }
        }

1
在Android 4中,可以通过Intent或跟随Bundle的Intent来发送数据。例如:Intent i = new Intent(current_class.this, linked_class.class); i.putextra("Key", value);,然后在另一个类中获取值(假设为字符串值)。
 String value = getIntent.getExtra("String key which you used when send value");
  • 选项2

    类A{

    public static String _utfValue = "";

    void sendValue(){ _utfValue = "一些值"; } }

并在您的Java类中获取此值:

String value = A._utfValue ;
  • 您可以使用SharedPreference保存值,并从其他类中获取它。
  • 您可以使用带有一些返回值的静态方法,并通过类名在您的Java类中获取该方法。

1
我正在分享代码,这是@Shadman Akhtar建议并由@Singee回复的。一旦按钮被点击,TextView值就会被设置为从retrivedata.java发送到MainActivity的值。我使用了按钮来模拟可以在retrivedata.java中的异步方法。

MainActivity.java

package com.example.interfacetesting;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements MyCustomInterface {
    TextView tv1;
    Button btn1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv1=(TextView)findViewById(R.id.tv1);
        btn1=(Button)findViewById(R.id.btn1);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                retrivedata rd=new retrivedata(MainActivity.this);
                rd.recievedataa();
            }
        });

    }

    @Override
    public void sendData(String str){

        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                tv1.setText(str);
            }
        });
    }
}

MyCustomInterface.java //这是接口

package com.example.interfacetesting;

public interface MyCustomInterface{
    public void sendData(String str);
}

retrivedata.java //从中数据将发送到MainActivity的类。

package com.example.interfacetesting;
public class retrivedata{

    private MyCustomInterface otherNameInterface;
    retrivedata(MyCustomInterface otherNameInterface){
        this.otherNameInterface = otherNameInterface;
    }
   void recievedataa()
   {
       otherNameInterface.sendData("---any string you want to send to mainactivity-------");
   }
}

0
也许你可以使用一个 Handler,将其加载一些数据,然后从你的活动中读取这些数据。在这里查看更多信息关于处理程序。
你只需要从你的活动传递一个处理程序到你的类中,在你的运行方法中使用 handler.sendMessage(""),并分析你在活动中接收到的内容即可。

0
在你的情况下,我会使用活动作为接口。该接口存储为 Application 类中的静态参数。

0

有很多方法可以实现这个,以下是一些方法:

  1. 您可以像其中一个答案中所解释的那样使用接口
  2. 您可以创建IntentService而不是您的类并使用ResultReceiver来通信数据。
  3. 您也可以使用处理程序和消息
  4. 您还可以创建一项服务并使用IBinders(绑定服务)

您可以搜索更多关于这些方法的内容,并选择最适合自己的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接