小小的总结一下Activity、Fragment、Service之间的通信方式:
1、intent(这个相信大家都用过,就不做过多解释了);
2、通过类的静态成员变量,类的静态成员变量可以通过类名访问;
3、通过全局变量进行通信;
4、第三种方式,可以借助内存外的工具进行通信:
3-1、使用Sqlite数据库;
3-2、SharePreference;
3-3、文件存储;
5、开启service,但开销较大,且service随时会挂掉,维护起来成本较大
activity向fragment中传递数据:
界面由activity跳转到fragment时,在activity中通过setArguments()方法保存Bundle数据,然后在fragment中通过
getArguments()方法获取Bundle数据。
activity中:
public class Main2Activity extends AppCompatActivity {
Button button = null;
EditText et = null;
MyFragment1 myFragment1 = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
button = findViewById(R.id.btn_activity2);
et = findViewById(R.id.et_activity2);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String dataACMain2 = et.getText().toString();
Bundle bundle = new Bundle();
if(myFragment1==null ) {
myFragment1 = new MyFragment1();
}
bundle.putString("dataACMain2", dataACMain2);
myFragment1.setArguments(bundle);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.activity_main2, myFragment1);
transaction.commit();
}
});
}
}
**fragment中:**
String data = getArguments().getString("dataACMain2");
tvFragment.setText(data);
fragment向activity中传递数据:
同样的一段代码:
主要原理是: 在fragment中定义一个接口并声明,然后调用接口方法传入要传给activity的数据,到activity中,activity需要实现这个接口,在接口方法中获取传过来的data;需要注意的是,在fragment中获取接口“实例”的时候是在onAttach()方法中,主要代码如下:
fragment中:
@Override
public void onAttach(Context context) {
super.onAttach(context);
myCallBack = (MyCallBack) getActivity();
}
public interface MyCallBack {
void sendData(String data);
}
activity中:
public class MainActivity extends AppCompatActivity implements MyFragment1.MyCallBack{
TextView tv_show = null;
EditText input = null;
Button button = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_show = findViewById(R.id.tv_show);
input = findViewById(R.id.et_ac_main);
button = findViewById(R.id.btn_main_send_data);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, Main2Activity.class));
/*String data = input.getText().toString();
Bundle bundle = new Bundle();
bundle.putString("data", data);
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.myFragment1);
fragment.setArguments(bundle);*/
}
});
}
@Override
public void sendData(String data) {
tv_show.setText(data);
}
}
activity向fragment传值:
接受消息的handler肯定是写在fragment中,然后在handleMessage()方法中更新UI,所以发送消息就应该写在activity中了,在这声明一个handler, 然后再点击事件中调用handler.sendMessage()方法,看起来似乎Ok了,那么如何保证activity中的handler和fragment中的handler是一个hanlder呢,可以在activity中定义一个setHandler方法,传入一个hander赋给activity的handler,然后可以在fragment的onAttach()方法中获取activity实例,再调用setHandler()方法即可,代码如下:
public class MainActivity extends AppCompatActivity {
Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendData = findViewById(R.id.btn_ac);
final EditText data = findViewById(R.id.et_ac);
sendData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = data.getText().toString();
Bundle bundle = new Bundle();
bundle.putString("data", s);
Message msg = Message.obtain();
msg.setData(bundle);
mHandler.sendMessage(msg);
}
});
}
public void setHandler(Handler handler) {
this.mHandler = handler;
}
}
public class Fragment1 extends Fragment {
MainActivity mActivity;
TextView tv;
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
tv.setText(msg.getData().getString("data"));
}
};
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fm1, container, false);
tv = view.findViewById(R.id.tv_fm);
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mActivity = (MainActivity) getActivity();
mActivity.setHandler(mHandler);
}
反过来试试,fragment向activity
同理,不过这次是在activity中创建一个handler,然后在fragment中定义一个setHandler()方法,在activity中获取fragment实例,用getSupportManager().findFragmentById()就行,然后后面的一样;
activity向fragment发送信息:
1、定义一个MessageEvent类;
public class MessageEvent {
private String message;
public MessageEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
2、activity中
发送MessageEvent事件
sendData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new MessageEvent(data.getText().toString()));
}
});
3、fragment中
首先需要注册订阅者:
EventBus.getDefault().register(this);
然后写一个接收MessegeEvent的事件(方法名任意写,只需要加上订阅注解就行)
@Subscribe
public void onMoonEvent(MessageEvent messageEvent) {
tv.setText(messageEvent.getMessage());
}
就是这么简单!!
我的天,我真的不想再多说啥了,在activity中一直报service空指针,原来是忘了在manifest中定义。。
好了,开始正文:
模拟一个使用service进行下载的进度条,首先定义一个service:
public class MyService extends Service{
public static final int MAX_PROGRESS = 100;
private int progress = 0;
public int getProgress() {
return progress;
}
public void startDownload() {
new Thread() {
@Override
public void run() {
super.run();
while (progress
然后是activity中;
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获取service实例
myService = ((MyService.MyBinder)service).getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
//更新进度条
public void onProgress() {
new Thread() {
@Override
public void run() {
super.run();
while (progress
然后其实更新ui的方式使用接口的方式更好,可以试一下。
在service中定义接口并定义传递接口的方法:
public void setOnProgressListener(OnProgressListener onProgressListener) {
this.mOnProgressListener = onProgressListener;
}
public interface OnProgressListener{
void onProgressChange(int progress);
}
然后传入要改变的数据:
public void startDownload() {
new Thread() {
@Override
public void run() {
super.run();
while (progress
activity中:
实现接口
myService.setOnProgressListener(new MyService.OnProgressListener() {
@Override
public void onProgressChange(int progress) {
onProgress(progress);
}
});
更新ui的方法:
public void onProgress(final int progress1) {
new Thread() {
@Override
public void run() {
super.run();
while (progress1 < MyService.MAX_PROGRESS) {
bar.setProgress(progress1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
这样更好一点;
当然可以用广播,比较简单,你们自己实现以下,这里就不贴代码了。。
1、通过接口回调的方式:
fragment和fragment之间不能直接通信,必须通过依赖的activity进行中转后才可通信:
通过接口:
步骤:1、在发送方定义接口(要发送数据的fragment);
2、在接受方实现接口(acitivity实现接口,获取数据,在实现的方法中调用另外一个fragment的公共方法);
3、传入数据;
例子中左边fragment向右边fragment发送数据:
代码如下:
```
public class LeftFragment extends Fragment {
EditText etFmLeft;
Button btnFmLeft;
DataListener dataListener;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_left, container, false);
etFmLeft = view.findViewById(R.id.et_fm_left);
btnFmLeft =view.findViewById(R.id.btn_fm_left);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
btnFmLeft.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String data = etFmLeft.getText().toString();
dataListener.showData(data);
}
});
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
dataListener = (DataListener) getActivity();
}
public interface DataListener{
void showData(String data);
}
}
public class MainActivity extends AppCompatActivity implements LeftFragment.DataListener{
RightFragment rightFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rightFragment= (RightFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_right);
}
@Override
public void showData(String data) {
rightFragment.showData(data);
}
}
public class RightFragment extends Fragment {
TextView tvShow;
LeftFragment.DataListener listener;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_right, container, false);
tvShow = view.findViewById(R.id.tv_fm_right);
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
listener = (LeftFragment.DataListener) getActivity();
}
public void showData(String data) {
tvShow.setText(data);
}
}
“`
2、通过广播:
同一个例子:
LeftFragment
String data = etFmLeft.getText().toString();
Intent intent = new Intent(“data”);
intent.putExtra(“data”, data);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
RightFragment
mLBM = LocalBroadcastManager.getInstance(getActivity());
IntentFilter filter = new IntentFilter(“data”);
mLBM.registerReceiver(receiver, filter);
}
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String data = intent.getStringExtra("data");
tvShow.setText(data);
}
};
3、通过Handler
参照activity和fragment通信可以做出来;
4、通过EventBus
和activity与fragment通信完全一样,可自行实现。
参考文章:
(http://blog.csdn.net/as4399/article/details/54799103)
EventBus的使用
(http://blog.csdn.net/u012702547/article/details/49786417)
activity与service间通信