麻烦运行Android后台服务

时间:2017-10-05 03:39:35

标签: android

我有一些简单的代码,用于启动后台服务,每秒更新一次来自MainActivity的静态整数。我还有一个按钮,当单击时,使用该静态整数的值更新TextView。但是,每次启动服务时,它只会增加一次值并停止,而不是连续递增,直到我按停止服务。

这是我的代码:

public class MainActivity extends AppCompatActivity {
    public static int count;

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

        count = 0;
    }

    public void pressButton(View view) {
        TextView textView = (TextView) findViewById(R.id.textView);
        textView.setText("" + count);
    }

    public void startService(View view) {
        startService(new Intent(getBaseContext(), MyService.class));
    }

    public void stopService(View view) {
        stopService(new Intent(getBaseContext(), MyService.class));
    }
}

我的服务:

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                MainActivity.count++;
            }
        }, 1000);
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

我无法弄清楚似乎是什么问题。

3 个答案:

答案 0 :(得分:1)

public class DownloadService extends IntentService {
   String pdfName = "";

   public DownloadService() {
       super("DownloadService");
   }

@Override
protected void onHandleIntent(@Nullable Intent intent) {
    showNotificationProgress();
    if (intent != null) {
        pdfName = intent.getStringExtra("pdfName");
    }
   downloadPDF ( ) // Implement this method
}

   public void writeBytesToFile(boolean status, String encodedString) {
    if (status && !TextUtils.isEmpty(encodedString)) {
        byte[] decodedArry = decodeBase64String(encodedString);
        String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + pdfName;
        File fileOut = new File(path);

        // if file doesnt exists, then create it
        if (!fileOut.exists()) {
            try {
                //noinspection ResultOfMethodCallIgnored
                fileOut.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try (FileOutputStream fileOuputStream = new FileOutputStream(fileOut)) {
            fileOuputStream.write(decodedArry);
            completed = true;
        } catch (IOException e) {
            completed = false;
            e.printStackTrace();
        } finally {
            if (completed) {
               //do something
            }
        }
    } else {
        hideNotificationProgress();
    }
}

 private static byte[] decodeBase64String(String encodedString) {
    return Base64.decode(encodedString, Base64.DEFAULT);
}

public static void hideNotificationProgress() {
    mNotifyManager.cancel(1);
}

private void showNotificationProgress() {
    final int id = 1;
    mNotifyManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
    mBuilder.setContentTitle("PDF Download")
            .setContentText("Download in progress")
            .setSmallIcon(android.R.drawable.stat_sys_download);
 // Start a lengthy operation in a background thread
    new Thread(
            new Runnable() {
                @Override
                public void run() {
                    // Do the "lengthy" operation 20 times
                    // Sets the progress indicator to a max value, the
                    // current completion percentage, and "determinate"
                    // state
                    mBuilder.setProgress(0, 0, true);
                    // Issues the notification
                    mNotifyManager.notify(id, mBuilder.build());
                    // Sleeps the thread, simulating an operation
                    // that takes time
                    try {
                        // Sleep for 5 seconds
                        Thread.sleep(1000);
                    } catch (InterruptedException ignored) {
                    }
                }
            }
 // Starts the thread by calling the run() method in its Runnable
    ).start();
}
}

为什么不试试像这样的Intent Service。

并按以下方式启动此服务

 Intent intent = new Intent(AActivity, DownloadService.class);
            intent.putExtra("pdfName", pdfName);
            holdingActivity.startService(intent);

答案 1 :(得分:1)

此代码显示如何从后台服务更新Android活动中的UI。

<强> BroadcastTest.java

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class BroadcastTest extends Activity {
    private static final String TAG = "BroadcastTest";
    private Intent intent;

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

        intent = new Intent(this, BroadcastService.class);
    }

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            updateUI(intent);       
        }
    };    

    @Override
    public void onResume() {
        super.onResume();       
        startService(intent);
        registerReceiver(broadcastReceiver, new IntentFilter(BroadcastService.BROADCAST_ACTION));
    }

    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(broadcastReceiver);
        stopService(intent);        
    }   

    private void updateUI(Intent intent) {
        String counter = intent.getStringExtra("counter"); 
        String time = intent.getStringExtra("time");
        Log.d(TAG, counter);
        Log.d(TAG, time);

        TextView txtDateTime = (TextView) findViewById(R.id.txtDateTime);   
        TextView txtCounter = (TextView) findViewById(R.id.txtCounter);
        txtDateTime.setText(time);
        txtCounter.setText(counter);
    }
}

<强> BroadcastService.java

import java.util.Date;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

public class BroadcastService  extends Service {
    private static final String TAG = "BroadcastService";
    public static final String BROADCAST_ACTION = "com.websmithing.broadcasttest.displayevent";
    private final Handler handler = new Handler();
    Intent intent;
    int counter = 0;

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

        intent = new Intent(BROADCAST_ACTION);  
    }

    @Override
    public void onStart(Intent intent, int startId) {
        handler.removeCallbacks(sendUpdatesToUI);
        handler.postDelayed(sendUpdatesToUI, 1000); // 1 second

    }

    private Runnable sendUpdatesToUI = new Runnable() {
        public void run() {
            DisplayLoggingInfo();           
            handler.postDelayed(this, 10000); // 10 seconds
        }
    };    

    private void DisplayLoggingInfo() {
        Log.d(TAG, "entered DisplayLoggingInfo");

        intent.putExtra("time", new Date().toLocaleString());
        intent.putExtra("counter", String.valueOf(++counter));
        sendBroadcast(intent);
    }

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

    @Override
    public void onDestroy() {       
        handler.removeCallbacks(sendUpdatesToUI);       
        super.onDestroy();
    }       
}

<强> RES /布局/ main.xml中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
        <TableLayout android:id="@+id/tableGPS"
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content"
            android:layout_marginTop="7px"
            android:stretchColumns="1"> 
            <TableRow 
                android:layout_margin="1dip">
                <TextView android:layout_gravity="right" 
                    android:text="Time:"
                    android:layout_marginRight="7px" 
                    android:layout_width="60px" />
                <TextView android:id="@+id/txtDateTime"
                    android:gravity="left"
                    android:layout_span="2" />
            </TableRow>
            <TableRow 
                android:layout_margin="1px">
                <TextView android:layout_gravity="right" 
                    android:text="Counter:"
                    android:layout_marginRight="7px"
                    android:layout_width="60px" />
                <TextView android:id="@+id/txtCounter" 
                    android:gravity="left" />
            </TableRow>
         </TableLayout> 
</LinearLayout>

答案 2 :(得分:0)

延迟后只运行一次。您需要安排重复发生的任务,或者只创建一个可以反复调用任务的Runnable。

 final Handler mHandler = new Handler();
    Runnable runner = new Runnable() {
            @Override
            public void run() {
                MainActivity.count++;
                mHandler.postDelayed(runner, 1000);
            }
        }

    mHandler.postDelayed(runner, 1000);