- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个带有 viewpager fragment 的 Android Activity 。在 Activity 的 onCreate 方法中,我将一个服务绑定(bind)到它,该服务在后台不断运行。
在 fragment 中,在特定条件下,我需要调用服务中处理该条件的函数。访问服务和调用其功能的正确方法是什么?
主 Activity .java
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivity";
DbHelper dbHelper;
SessionManager sessionManager;
SessionCache sessionCache;
Map<String, ?> userDetails;
protected SocketListener socketService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sessionManager = new SessionManager(getApplicationContext());
// Connect to background socketlistener service
Intent serviceIntent = new Intent(MainActivity.this, SocketListener.class);
startService(serviceIntent);
.
.
.
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("").setIcon(getResources().getDrawable(R.drawable.profileicon)));
tabLayout.addTab(tabLayout.newTab().setText("").setIcon(getResources().getDrawable(R.drawable.homeicon)));
tabLayout.addTab(tabLayout.newTab().setText("").setIcon(getResources().getDrawable(R.drawable.chaticon)));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final NonSwipeableViewPager viewPager = (NonSwipeableViewPager) findViewById(R.id.view_pager);
final CustomPagerAdapter pagerAdapter = new CustomPagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pagerAdapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
viewPager.setCurrentItem(1);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
socketService = ((SocketListener.LocalBinder) iBinder).getService();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
socketService = null;
}
};
}
这是我的服务。我连接到服务器,并不断监听更新。
套接字监听器.java
package com.example.gopa2000.mobapps;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import java.net.URISyntaxException;
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
public class SocketListener extends Service {
private static String TAG = "SocketListener";
private Socket socket;
public SocketListener() { }
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return localBinder;
}
private final IBinder localBinder = new LocalBinder();
public class LocalBinder extends Binder {
public SocketListener getService(){
Log.i(TAG, "getService: Sitting in local binder.");
return SocketListener.this;
}
public void sendMessage(String message){
socket.emit("match", message);
}
}
@Override
public void onCreate() {
super.onCreate();
}
public void isBoundable(){
Log.i(TAG, "Bind like a baller.");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Runnable connect = new ConnectSocket();
new Thread(connect).start();
return START_STICKY;
}
class ConnectSocket implements Runnable {
@Override
public void run() {
try {
socket = IO.socket(RESTClient.getURL());
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.i(TAG, "call: Connected to backend!");
}
});
socket.connect();
} catch (URISyntaxException e){
Log.e(TAG, "run: ", e);
}
}
}
public Socket getSocket(){
return this.socket;
}
}
这是我需要调用 sendMessage(string)
的 fragment 。
public class MainViewFragment extends Fragment {
private final String TAG = "MVFragment";
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
private SessionManager sessionManager;
private ArrayList<CustomCard> cards;
private CardAdapter cardAdapter;
private Button btn;
private SwipeFlingAdapterView flingContainer;
private Map<String, ?> userDetails;
// hax
private static String userEmail;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.from(getContext()).inflate(R.layout.fragment_main_view, container, false);
.
.
flingContainer.setAdapter(adapter);
flingContainer.setFlingListener(new SwipeFlingAdapterView.onFlingListener(){
.
.
@Override
public void onRightCardExit(Object o) {
.
.
if(match){
// need to call sendMessage from the service here. <------------------------
sessionCache.addToMatchTable(Liker, Likee);
}
}
@Override
public void onAdapterAboutToEmpty(int i) {
}
@Override
public void onScroll(float v) {
}
});
flingContainer.setOnItemClickListener(new SwipeFlingAdapterView.OnItemClickListener(){
@Override
public void onItemClicked(int itemPosition, Object dataObject){
Toast.makeText(getActivity(), "Clicked!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getActivity().getApplicationContext(), FullScreenCardLayout.class);
startActivity(intent);
}
});
return view;
}
最佳答案
首先 sendMessage(message)
方法应该在服务内部而不是 LocalBinder
类
public class SocketListener extends Service {
public void sendMessage(String message){
socket.emit("match", message);
}
}
其次要从 fragment 访问 Activity 方法,您应该在 fragment 内创建接口(interface)
interface MessageSender {
void sendMessage(String message);
}
然后在你的 Activity 中实现它
public class MainActivity extends AppCompatActivity implements MessageSender {
@Override
public void sendMessage(String message) {
// call the service here
socketService.sendMessage(message);
}
}
在您的 fragment 中,实现onAttach()
并初始化接口(interface)实例
public class MainViewFragment extends Fragment {
private MessageSender mMessageSenderCallback;
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mMessageSenderCallback = (MessageSender) context;
} catch (ClassCastException e) {
// Error, class doesn't implement the interface
}
}
@Override
public void onDetach() {
super.onDetach();
// Remove activity reference
mMessageSenderCallback = null;
}
}
要发送消息,请调用 mMessageSenderCallback.sendMessage(message)
并将您的消息放入 fragment 中。
关于java - 如何从绑定(bind)到 Android 父 Activity 的 fragment 访问服务功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40750712/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
PowerShell Web Access 允许您通过 Web 浏览器运行 PowerShell cmdlet。它显示了一个基于 Web 的控制台窗口。 有没有办法运行 cmdlet 而无需在控制台窗
我尝试在无需用户登录的情况下访问 Sharepoint 文件。 我可以通过以下任一方式获取访问 token 方法一: var client = new RestClient("https://logi
我目前正在尝试通过 Chrome 扩展程序访问 Google 服务。我的理解是,对于 JS 应用程序,Google 首选的身份验证机制是 OAuth。我的应用目前已成功通过 OAuth 向服务进行身份
假设我有纯抽象类 IHandler 和派生自它的类: class IHandler { public: virtual int process_input(char input) = 0; };
我有一个带有 ThymeLeaf 和 Dojo 的 Spring 应用程序,这给我带来了问题。当我从我的 HTML 文件中引用 CSS 文件时,它们在 Firebug 中显示为中止。但是,当我通过在地
这个问题已经有答案了: JavaScript property access: dot notation vs. brackets? (17 个回答) 已关闭 6 年前。 为什么这不起作用? func
我想将所有流量重定向到 https,只有 robot.txt 应该可以通过 http 访问。 是否可以为 robot.txt 文件创建异常(exception)? 我的 .htaccess 文件: R
我遇到了 LinkedIn OAuth2: "Unable to verify access token" 中描述的相同问题;但是,那里描述的解决方案并不能解决我的问题。 我能够成功请求访问 toke
问题 我有一个暴露给 *:8080 的 Docker 服务容器. 我无法通过 localhost:8080 访问容器. Chrome /curl无限期挂断。 但是如果我使用任何其他本地IP,我就可以访
我正在使用 Google 的 Oauth 2.0 来获取用户的 access_token,但我不知道如何将它与 imaplib 一起使用来访问收件箱。 最佳答案 下面是带有 oauth 2.0 的 I
我正在做 docker 入门指南:https://docs.docker.com/get-started/part3/#recap-and-cheat-sheet-optional docker-co
我正在尝试使用静态 IP 在 AKS 上创建一个 Web 应用程序,自然找到了一个带有 Nginx ingress controller in Azure's documentation 的解决方案。
这是我在名为 foo.js 的文件中的代码。 console.log('module.exports:', module.exports) console.log('module.id:', modu
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用 MGTwitterEngine"将 twitter 集成到我的应用程序中。它在 iOS 4.2 上运行良好。当我尝试从任何 iOS 5 设备访问 twitter 时,我遇到了身份验证 to
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用以下 API 列出我的 Facebook 好友。 https://graph.facebook.com/me/friends?access_token= ??? 我想知道访问 token 过
401 Unauthorized - Show headers - { "error": { "errors": [ { "domain": "global", "reas
我已经将我的 django 应用程序部署到 heroku 并使用 Amazon s3 存储桶存储静态文件,我发现从 s3 存储桶到 heroku 获取数据没有问题。但是,当我测试查看内容存储位置时,除
我是一名优秀的程序员,十分优秀!