繁体   English   中英

避免将销毁活动中的null发送到重新启动的服务

[英]avoid of send null from destroyed activity to restarted service

我想在后台编程应用程序以进行数据跟踪,所以我使用服务。 我想编写一个程序来监视设备发送和接收的所有数据,并且当接收或接收的消息总量达到指定值时,Internet设备将关闭。

因此,我使用以下代码监视数据:

mStartRX = TrafficStats.getTotalRxBytes ();
mStartTX = TrafficStats.getTotalTxBytes ();

我使用这些服务在后台运行后台。

为了使用edittext从用户指定下载或上传限制,我在mainactivity中请求了此限制,并将此值发送到服务。

问题出在什么时候:当我销毁程序时,我将重新启动服务并获取NULL值,并且程序崩溃。

我的应用程序代码:

主要活动 :

package ir.alexandre9009.service;


import android.app.AlertDialog;
import android.content.Context;
import android.net.TrafficStats;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {
    public static Handler mHandler = new Handler();
public static long UPP;
public static long DLL;
    Button startService,stopService;
    public Context context=this;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (FirstService.mStartRX == TrafficStats.UNSUPPORTED || FirstService.mStartTX == TrafficStats.UNSUPPORTED) {
            AlertDialog.Builder alert = new AlertDialog.Builder(this);
            alert.setTitle("Uh Oh!");
            alert.setMessage("Your device does not support traffic stat monitoring.");
            alert.show();
        } else {
            mHandler.postDelayed(mRunnable, 1000);
        }
        startService=(Button)findViewById(R.id.startService);
        stopService=(Button)findViewById(R.id.stopService);

        startService.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                EditText UP = (EditText) findViewById(R.id.UP);
                String UPPP = UP.getText().toString();
                UPP=Long.parseLong(UPPP);

                EditText DL = (EditText) findViewById(R.id.DL);
                String DLLL = DL.getText().toString();
                DLL=Long.parseLong(DLLL);
                Intent intent = new Intent(getApplicationContext(), FirstService.class);
                String myString = DLLL;
                intent.putExtra("StringName", myString);
                startService(intent);
            }

        });

        stopService.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                stopService(new Intent(getBaseContext(),FirstService.class));
            }
        });
    }
    public final Runnable mRunnable = new Runnable() {
        public void run() {
            TextView RX = (TextView)findViewById(R.id.RX);
            TextView TX = (TextView)findViewById(R.id.TX);
            RX.setText(Long.toString(FirstService.rxBytes));
            TX.setText(Long.toString(FirstService.txBytes));
            mHandler.postDelayed(mRunnable, 1000);
        }
    };
}

服务内容:

package ir.alexandre9009.service;

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.TrafficStats;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.IBinder;
import android.widget.TextView;
import android.widget.Toast;

public class FirstService extends Service{
    public static long mStartRX ;
    public static long mStartTX ;
    public static long rxBytes ;
    public static long txBytes ;
    public long dl=MainActivity.DLL;
    Context context=this;
    private final Runnable mRunnable = new Runnable() {
        public void run() {

            rxBytes = (TrafficStats.getTotalRxBytes()- mStartRX)/1048576;
            txBytes = (TrafficStats.getTotalTxBytes()- mStartTX)/1048576;
            if (rxBytes==2) {
                stopService(new Intent(getBaseContext(),FirstService.class));
                Intent i = new Intent(context,MainActivity.class);
                context.startActivity(i);

                //  WifiManager wifiManager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
               // wifiManager.setWifiEnabled(false);
//معرفی توست برای نمایش یک پیام کوتاه به کاربر در هنگام خاموش کردن وای فای
                Toast.makeText(FirstService.this, "هشدار", Toast.LENGTH_LONG).show();

            }
            mHandler.postDelayed(mRunnable, 1000);
        }
    };
    private Handler mHandler = new Handler();

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Toast.makeText(this,"staart",Toast.LENGTH_LONG).show();
        mStartTX=0;
        mStartRX=0;
        mStartRX = TrafficStats.getTotalRxBytes();
        mStartTX = TrafficStats.getTotalTxBytes();
        mHandler.postDelayed(mRunnable, 1000);

        return Service.START_STICKY;


    }

    @Override
    public void onDestroy() {
        TrafficStats.clearThreadStatsTag();
        Toast.makeText(this,"FirstService Stoped",Toast.LENGTH_LONG).show();
        mStartTX=0;
        mStartRX=0;
        super.onDestroy();
    }



}

AndroidManifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ir.alexandre9009.service">
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".FirstService"

            >

        </service>
    </application>

</manifest>

请帮我 ...

问题是这条线

公共长dl = MainActivity.DLL;

您是在Activity中引用一个变量,很可能在Activity被销毁时,该变量不再在作用域内,因此您会得到Null Exception。

您必须使用意图获得此值。

另一个问题是,除了需要向用户显示通知的前台服务之外,您无法阻止任何服务被系统杀死。 但这不适合您的情况。

因此,最适合您的方法是检查intent是否为null。 如果不为null,则获取该值并将其保存到“首选项”或“数据库”中,如果为null,则从之前存储该值的位置检索该值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM