我怎样才能在 android 中保持状态 'online'

How can i keep status 'online' in android

现在我正在尝试使用 firebase 制作一个类似 Instagram 的聊天程序 问题是我想显示会员登录状态 但是 android 生命周期有问题

这是我的代码 HomeActiviy 用户登录成功后,进入HomeActivty 从这里我确定在线或离线

这是我区分线上线下的代码

    private void status(String status){
        reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("status", status);

        reference.updateChildren(hashMap);

    }

    @Override
    protected void onResume() {
        super.onResume();
        status("online");
    }


    @Override
    protected void onPause() {
        super.onPause();
        status("offline");
    }

来自我的 HomeActivity.java 推送聊天时的 ImageButton 转到聊天 Activity 他们看到对方的在线图片按钮为绿色或灰色

这是我的问题 什么时候从家Activity去另一个activity 状态将显示离线

第二次是我按下聊天按钮

这是我的聊天记录Activity

package com.example.together.activities.chat;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.widget.TextView;


import com.bumptech.glide.Glide;
import com.example.together.fragment.ChatFragment;
import com.example.together.fragment.UsersFragment;
import com.example.together.model.User;
import com.example.together.R;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.HashMap;

import de.hdodenhof.circleimageview.CircleImageView;

public class ChatsActivity extends AppCompatActivity {

    CircleImageView image_profile;
    TextView username;

    FirebaseUser firebaseUser;
    DatabaseReference reference;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle("");

        image_profile = findViewById(R.id.image_profile);
        username = findViewById(R.id.username);

        firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());

        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                User user = dataSnapshot.getValue(User.class);
                username.setText(user.getUsername());
                if (user.getImageurl().equals("default")){
                    image_profile.setImageResource(R.mipmap.ic_launcher);
                }else {
                    Glide.with(ChatsActivity.this).load(user.getImageurl()).into(image_profile);
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        TabLayout tabLayout = findViewById(R.id.tab_layout);
        ViewPager viewPager = findViewById(R.id.view_pager);

        ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

        viewPagerAdapter.addFragment(new ChatFragment(), "채팅");  // `new ChatFragment()` should be inside `FragmentPagerAdapter.getItem()`
        viewPagerAdapter.addFragment(new UsersFragment(), "친구찾기");  // `new UsersFragment()` should be inside `FragmentPagerAdapter.getItem()`

        viewPager.setAdapter(viewPagerAdapter);

        tabLayout.setupWithViewPager(viewPager);



    }


    class ViewPagerAdapter extends FragmentPagerAdapter {

        private ArrayList<Fragment> fragments; // this line can cause crashes
        private ArrayList<String> titles;

        ViewPagerAdapter(FragmentManager fm){
            super(fm);
            this.fragments = new ArrayList<>();
            this.titles = new ArrayList<>();
        }

        @Override
        public Fragment getItem(int position) {
            return fragments.get(position);
        }

        @Override
        public int getCount() {
            return fragments.size();
        }

        public void addFragment(Fragment fragment, String title){
            fragments.add(fragment); // this line can cause crashes
            titles.add(title);
        }


        // Ctrl + O


        @Nullable
        @Override
        public CharSequence getPageTitle(int position) {
            return titles.get(position);
        }
    }



}

这是我的错误

2019-07-09 16:46:29.993 13773-13773/com.example.blogapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.blogapp, PID: 13773
    java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
        at com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed(RequestManagerRetriever.java:323)
        at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:132)
        at com.bumptech.glide.Glide.with(Glide.java:741)
        at com.example.together.activities.chat.ChatsActivity.onDataChange(ChatsActivity.java:66)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@17.0.0:75)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@17.0.0:63)
        at com.google.firebase.database.core.view.EventRaiser.run(com.google.firebase:firebase-database@@17.0.0:55)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

我认为它与 activity

的生命周期相关

如何保持状态?

问题看起来是您的 ChatsActivity 在 Glide 尝试加载图像时被破坏了。您可以使用 getApplicationContext() 来获取当前上下文。 尝试替换,

Glide.with(ChatsActivity.this).load(user.getImageurl()).into(image_profile);

Glide.with(getApplicationContext()).load(user.getImageurl()).into(image_profile);

此外,您应该使用 firebase 提供的 .onDisconnect() 方法来检查用户是否存在

When you establish an onDisconnect() operation, the operation lives on the Firebase Realtime Database server. The server checks security to make sure the user can perform the write event requested, and informs the your app if it is invalid. The server then monitors the connection. If at any point the connection times out, or is actively closed by the Realtime Database client, the server checks security a second time (to make sure the operation is still valid) and then invokes the event.

你可以从这里了解更多doc

将此依赖项放入您的 build.gradle 文件中:

implementation "android.arch.lifecycle:extensions:*"

然后在您的应用程序 class 中使用:

public class MyApplication extends Application implements LifecycleObserver {

    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private void onAppBackgrounded() {
        Log.d("MyApp", "App in background");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    private void onAppForegrounded() {
        Log.d("MyApp", "App in foreground");
    }
}

更新您的 AndroidManifest.xml 文件:

<application
    android:name=".MyApplication"
    ....>
</application>

When your app is in background change status to offline and when app is in foreground change it's status to online.

Reference

只要用户在您的应用中,从技术上讲,他就是在线的。所以在你家 activity 使用这个:

  @Override
    protected void onStart() {
        super.onStart();
        myRef.child(uid).child("isOnline").setValue(true);
        myRef.child(uid).child("isOnline").onDisconnect().setValue(false);
    }

而且我建议添加以覆盖 onResume():

    @Override
    protected void onResume() {
        super.onResume();
            myRef.child(uid).child("isOnline").setValue(true); //User back online

        }

确保添加一个 if 语句来检查用户是否连接到互联网!